2013-05-29 2 views
0
class Subject 
    has_many :subject_attribute_types 
    has_many :subject_attributes 

    accepts_nested_attributes_for :subject_attributes 
end 

class SubjectAttributeType 
    belongs_to :subject 
    has_many :subject_attributes 

    attr_accessible :type_name 
end 

class SubjectAttribute 
    belongs_to :subject 
    belongs_to :subject_attribute_type 

    attr_accessible :value 
end 

Например:
поиск nested_attributes в рельсах

s1 = Subject.create() 
s2 = Subject.create() 

sat1 = SubjectAttributeType.create(subject: s1, name: 'Age') 
sat2 = SubjectAttributeType.create(subject: s1, name: 'Sex') 

sat3 = SubjectAttributeType.create(subject: s2, type_name: 'Age') 
sat5 = SubjectAttributeType.create(subject: s2, type_name: 'Username') 

SubjectAttribute.create(subject: s1, subject_attribute_type: sat1, value: 20) 
SubjectAttribute.create(subject: s1, subject_attribute_type: sat2, value: "male") 
SubjectAttribute.create(subject: s2, subject_attribute_type: sat3, value: 21) 
SubjectAttribute.create(subject: s2, subject_attribute_type: sat1, value: "user1") 

Проблема:
Что лучшая практика, чтобы сделать поиск по точному subject_attributes.
Если я хочу, чтобы найти все субъекты с возрастом> = 18 и прозвище, как% пользователя%

В настоящее время я использую Ransack камень, но я не могу думать о том, как сделать поиск по nested_attributes

ответ

0

I см. проблема в бизнес-логике вашего приложения. Зачем вам нужен ваш атрибут AttributeType, чтобы узнать о каком-либо предмете?

class Subject < ActiveRecord::Base 
    has_many :subject_attributes 
    has_many :attribute_types, through: :subject_attributes 
end 

class SubjectAttribute < ActiveRecord::Base 
    belongs_to :attribute_type 
    belongs_to :subject 
    attr_accessible :attribute_type_id, :subject_id, :value 
end 

class AttributeType < ActiveRecord::Base 
    attr_accessible :type_name 
end 

После этого, если вы вставляете некоторые данные:

s1 = Subject.create 
s2 = Subject.create 

sat1 = AttributeType.create(type_name: "Age") 
sat2 = AttributeType.create(type_name: "Sex") 
sat3 = AttributeType.create(type_name: "Username") 

SubjectAttribute.create(subject:s1, attribute_type:sat1, value: 20) 
SubjectAttribute.create(subject:s1, attribute_type:sat2, value:"male") 
SubjectAttribute.create(subject:s2, attribute_type:sat1, value:21) 
SubjectAttribute.create(subject:s2, attribute_type:sat3, value:"user1") 

вы сможете сделать выбирает. В вашем примере вы используете несколько атрибутов, так что вы должны сделать несколько запросов:

таким образом, вы найдете предмет с именем значения:

names = Subject.joins(:attribute_types).where("attribute_types.type_name = 'Username' 
               and value like '%user%'") 
=> [#<Subject id: 2, created_at: "2013-05-29 11:11:51", updated_at: "2013-05-29 11:11:51">] 

Таким образом, вы найдете предмет со значением возраста

ages = Subject.joins(:attribute_types).where("attribute_types.type_name = 'Age' 
               and value >= 18") 
=> [#<Subject id: 1, created_at: "2013-05-29 11:11:42", updated_at: "2013-05-29 11:11:42">, 
    #<Subject id: 2, created_at: "2013-05-29 11:11:51", updated_at: "2013-05-29 11:11:51">] 

Таким образом, вы найдете пересекаемых предметы

subjects = (names&ages) 
=> [#<Subject id: 2, created_at: "2013-05-29 11:11:51", updated_at: "2013-05-29 11:11:51">] 

Использование dynamic attribute_types делает выбор очень сложным. поэтому, если вы согласны с отдельным запросом для каждого параметра типа-значения, используйте его. В противном случае, может быть, это действительно просто столбцы Субъектов?

+0

1) Бизнес-логика. Да! Вы абсолютно правы, в ассоциации Subject для AttributeType не было необходимости. 2) _Otherwise, может быть, это действительно просто столбцы Субъектов? _ Не решение, в будущем в mby будет добавлен новый атрибут AttributeType. «Вес или высота», например. Pluss не все AttributeTypes используются в каждом предмете. 3) несколько запросов да, это решение, но дает ту же проблему, что и с новым атрибутом AttributeType также необходимо добавить запрос. – maxnov

+0

вы все еще можете сделать это на лету: пара foreach делает запрос, а затем пересекает их с &. И это, если только вам нужны все атрибуты для фильтрации ваших предметов. –

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