说我有以下STI模型
class Parent < ActiveRecord::Base
has_many :childs, foreign_key: 'parent_id' # forgive the english for sake of simplicity
#def childs
# Child.where(parent_id: id) # this works just fine BTW
#end
end
class BadParent < Parent
end
class GoodParent < Parent
end
以及以下Child类
class Child
belongs_to :parent # parent_id lives on this
end
我不关心在Child上设置类型,所以我不关心创建多态关联。
bad_parent = BadParent.create(name: 'Michael Jackson')
child = Child.create(name: 'Bobby', parent: bad_parent)
如果我跑
child.parent #=> <# BadParent > # AWESOME
bad_parent.childs #=> [] NO BUENO!!!
sql_statement = bad_parent.childs.to_sql #=> "SELECT `childs`.* FROM `childs` WHERE `childs`.`parent_id` = 1"
Child.find_by_sql(sql_statement) #=> [<# Child Object #>] BUENO!!!
我是否有必要添加到关联中以使其像find_by_sql
一样工作?
答案 0 :(得分:3)
根据其他评论,你不应该同时拥有一个名称相同的方法和关联,因为它不清楚会被执行的内容 - 我会假设在这里你将摆脱<div class="like-buttons">
<img src="up.png" onclick="onClick(this)" />
<span id="clicks">0</span>
<img src="down.png" onclick="onClick(this)" />
</div>
除了我认为你的问题与缓存有关,即如果知道某些内容已发生变化,则只会触及数据库。在您的示例中,bad_parent不知道已添加新子项。您可以重新加载,如:
def childs ...
或强制调用数据库,如:
bad_parent.reload
bad_parent.childs #> should show child object now
请查看rials指南的3.1控制缓存部分以获取更多信息:http://guides.rubyonrails.org/association_basics.html
答案 1 :(得分:1)
这就是我要做的......
#app/models/person.rb
class Person < ActiveRecord::Base
#columns id | type | parent_id | type_id | name | created_at | updated_at
end
#app/models/parent.rb
class Parent < Person
belongs_to :type
has_many :children, foreign_key: 'parent_id'
end
#app/models/child.rb
class Child < Parent
belongs_to :parent
end
#app/models/type.rb
class Type < ActiveRecord::Base
#columns id | type
#values good/bad (probably overkill to have DB for this)
has_many :parents
end
这应该允许您调用以下内容:
@parent = Parent.find params[:id]
@parent.children #-> collection of Person model with parent_id attribute for parent
关于你的具体问题 - 关于eager loading
等 - 我没有大量的经验。
hierarchy gems可以帮助解决这个问题。
我们之前使用过ClosureTree
- 它创建了一个单独的表,使您可以更轻松地遍历层次结构。另一个名为ancestry
,非常受欢迎(更容易实现)。
我建议您在“父”模型中使用ancestry
之类的内容。我调用了父模型Parent
,因为我认为它将为您提供更深入的范围来处理不同类型的数据。
例如,您的Child
模型完全属于它,应该由与Parent
相同的数据组成。