这似乎是一个简单的问题,但这对我来说有点困惑:
class Parent
has_many children
...
end
class Child
belongs_to parent
end
p = Parent.find(111)
c = Child.all.where(parent: p)
为什么不起作用,我该怎么做:
c = Child.all.where(parent_id: p.id)
谢谢!
*附录*
更复杂的情况是我根据更复杂的逻辑创建了一个关系,例如
c = Child.where(age: 32, city: "boston")
c.where(parent: p) # wouldn't work
*附录#2 *
等等我需要多对多来说明这一点:
class Teacher
has_many :students, through: ClassRoom
has_many :classes
end
class ClassRoom
belongs_to :teacher
belongs_to :child
end
class Child
has_many :classes
has_many :teachers, through: ClassRoom
end
t = Teacher.first
c = Child.where(age: 5, city: "boston")
c.where(teacher: t) # wouldn't work
c.where(teacher_id: t.id) # would work but is a little ugly
*附录3 *
感谢所有精彩信息!从上面的例子开始,最后一行是否有更好(或'正确')的方式?
c.where(teacher_id: t.id) # would work but is a little ugly
答案 0 :(得分:3)
你可以这样做:
p = Parent.find(111)
all_children = p.children
关键的父级不起作用,因为它使用它作为列名。
附录:
因此,对于此用例,您应该使用:
class ClassRoom < ActiveRecord::Base
belongs_to :teacher
belongs_to :child
end
class Teacher < ActiveRecord::Base
has_many :children, through: ClassRoom
has_many :class_rooms
end
class Child < ActiveRecord::Base
has_many :class_rooms
has_many :teachers, through: ClassRoom
end
t = Teacher.first
teachers_children_from_boston_and_32 = t.children.where(age: 32, city: "boston")
首先,您不能使用Class,因为它已经是一个对象。 下一个问题是您将孩子重命名为学生,您可以这样做,但需要在has_many调用上做一些其他选项。
在此处查看加入表:http://guides.rubyonrails.org/active_record_querying.html#joining-tables
和Assoications在这里(你的用例完全符合这个例子): http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
还要记住rails 3所有where子句只是critera。 Critera用于查找您的匹配项,可以一起添加以缩小搜索结果范围。 IE
where_clause_one = Teacher.where(age: 50)
where_clause_two = Teacher.where(city: "San Francisco")
merged_where_clauses = where_clause_one.merge(where_clause_two)
merged_where_clauses.each do |teacher|
# teachers that are both 50 and from san francisco
...
end
答案 1 :(得分:3)
.all
将ActiveRecord :: Relation对象转换为数组。数组不响应where
方法。你应该使用
c = Child.where(parent_id: p.id).all
在这种情况下你必须使用_id,因为where
会直接将给定的哈希转换为SQL。 SQL不知道parent
是什么,它只知道parent_id
是什么。话虽如此,最好的方法是
c = p.children
答案 2 :(得分:2)
“Active Record对象不直接指定其属性,而是从与其链接的表定义中推断出它们” - http://api.rubyonrails.org/files/activerecord/README_rdoc.html
此关联由特定数据库列链接,因此您必须使用这些属性来引用关系。
您还可以使用p.children
来简化此声明,{{1}}将返回父母子女的数组。