我的应用程序中有一个结构,其中每个blog
条目都与一个pillar
相关联。在我的blogs#show
上,我有以下定义:
@pillar = Pillar.where(id: @blog.pillars_id)
但是,当我进入博客页面并尝试访问@pillar.name
时,会得到“支柱”而不是支柱名称(例如,“一般信息”或“为您的购房融资”)。当我调试并向错误页面询问@pillar
时,它显示以下内容:
<ActiveRecord::Relation [#<Pillar id: 2, name: "Financing Your Home Purchase", buyer: true, seller: false, active: true, menu: false, snippet: "Another test snippet. Should I be thinking wittil...", description: "It is our choices Harry that show what we truly ar...", created_at: "2018-07-03 16:50:55", updated_at: "2018-07-03 16:50:55">]>
如果有帮助,可以使用blog
belongs_to
,pillar
和pillar
has_many
blogs
。
任何人都可以弄清楚这里发生了什么吗?
答案 0 :(得分:3)
@pillar = Pillar.where(id: @blog.pillars_id)
返回一个ActiveRecord::Relation
,而不是一个Pillar
。您可以尝试:
@pillar = Pillar.where(id: @blog.pillars_id).first
或
@pillar = Pillar.find_by(id: @blog.pillars_id)
您也可以这样做:
@pillar = Pillar.find(@blog.pillars_id).
但是,如果没有Pillar
和指定的id
,则会抛出错误。
(您确定它是pillars_id
而不是pillar_id
吗?)
购买为什么不这样做:
@pillar = @blog.pillar
在您的控制器中-因为您大概已正确设置了关联。然后,您可以在视图中使用@pillar.name
。
或者,您可以执行以下操作:
@blog.pillar.name
我并不特别喜欢视图中的@blog.pillar.name
(因为您的视图必须对Blog
和Pillar
有很多了解)。即使在视图中使用@pillar.name
,也意味着您的视图必须了解有关Pillar
的知识(特别是,该方法有一个称为name
的方法)。我想我愿意这样做:
@pillar_name = @blog.pillar.name
在您的控制器中,并在视图中使用@pillar_name
。这样,您的视图就不必了解Blog
或Pillar
。
在这种情况下,您的控制器相当了解Blog
和Pillar
。您可以可以做
class Blog < ActiveRecord::Base
def pillar_name
pillar.name
end
end
现在,在您的控制器中,您可以执行以下操作:
@pillar_name = @blog.pillar_name
在这种情况下,您的控制器对Blog
一无所知,而对Pillar
一无所知。
但是,Blog
仍然需要了解Pillar
。因此,您可以这样做:
class Blog < ActiveRecord::Base
delegate :piller_name, to: :pillar
end
和
class Pillar < ActiveRecord::Base
alias pillar_name name
end
,以便Blog
对Pillar
知之甚少。
另外,请参阅评论,以获得@spike的非常好的建议,例如:
class Blog < ActiveRecord::Base
delegate :name, to: :pillar, prefix: true
end
然后,您可以忽略对Pillar
的修改。