2012-04-12 5 views
0

Помогите новичкам выбрать лучший способ реализации наследования в RoR3. У меня есть:Наследование моделей в Ruby on Rails 3

 
-Person (address fields, birthdate, etc.) 
    -Player, inherits from Person (position, shoe_size, etc.) 
     -Goalkeeper, inherits from Player (other specific fields related to this role) 

Я думаю, что одной таблицы Наследование является плохим решением, потому что там будет много пустых полей в таблице, созданной. Каков наилучший способ сделать это? Использовать полиморфные ассоциации (с has_one?)? Используйте belongs_to/has_one (но тогда, как показывать в Player, просматривает поля Person тоже?)? Не применять наследование? Другие решения?

ответ

1

Хотя я думаю, что ИППП, вероятно, подход, который я хотел бы использовать для этого, еще одна возможность, если вы хотите, чтобы избежать большого количества NULL атрибутов, чтобы добавить столбец other_attributes к модели личности, которая будет хранить Hash атрибутов , Чтобы сделать это, добавьте text столбец в таблице people:

def self.up 
    add_column :people, :other_attributes, :text 
end 

Затем убедитесь, что атрибут сериализации в модели. И вы можете написать обертку, чтобы убедиться, что она инициализируется как пустой Hash, когда вы используете его:

class Person < ActiveRecord::Base 
    serialize :other_attributes 

    ... 

    def other_attributes 
    write_attribute(:other_attributes, {}) unless read_attribute(:other_attributes) 
    read_attribute(:other_attributes) 
    end 
end 

Затем вы можете использовать атрибут следующим образом:

p = Person.new(...) 
p.other_attributes       #=> {} 
pl = Player.new(...) 
pl.other_attributes["position"] = "forward" 
pl.other_attributes       #=> {"position" => "forward"} 

Один нюанс с этим подходом заключается в том, что вы должны использовать строки как ключи при извлечении данных из other_attributes, поскольку ключи всегда будут строками, когда Hash извлекается из базы данных.

0

Я предлагаю ИППП. Альтернативным решением является использование хранилища документов, такого как mongodb, или использование магазина activerecord http://api.rubyonrails.org/classes/ActiveRecord/Store.html. Если у вас есть postgress database, посмотрите на его столбец HStore http://rubygems.org/gems/activerecord-postgres-hstore.

Другой вариант - наследование таблицы PostgreSQL. http://www.postgresql.org/docs/8.1/static/ddl-inherit.html

Смежные вопросы