【问题标题】:Ruby on Rails: Simply Can Not Render Nested AttributesRuby on Rails:根本无法渲染嵌套属性
【发布时间】:2012-10-18 00:31:02
【问题描述】:

我希望能够显示喜欢用户帖子的用户。我将提供一些简单的信息,以免这个问题变得不堪重负。

我涉及三个类:用户、分享和意见。他们的模型也是这样设置的:

class User
  has_many :opinions, foreign_key: "fan_id", dependent: :destroy
end

class Share
  has_many :opinions, foreign_key: "like_id", dependent: :destroy
  has_many :likes, through: :opinions
  has_many :agreeables, foreign_key: "fan_id", class_name: "Opinion", dependent: :destroy
  has_many :fans, through: :agreeables
end

class Opinion
  belongs_to :fan, class_name: "User"
  belongs_to :like, class_name: "Share"
end

换句话说:like_id = share.id & fan_id = user.id

然后在我的控制器中:

SharesController
  def show
    @share = Share.find(params[:id])
    @shares = @share.fans.paginate(page: params[:page])
  end

我单击指向share_path 的链接,它呈现页面但上面没有任何内容。当我查看我的 SQL 日志时,我注意到了问题:

将呈现的共享 (like_id) 与喜欢共享的用户 (fan_ids) 匹配不是正确的内部加入意见。

假设share.id 是 11,current_user.id 是 5。它的查询主要包括具有 like_id 的内部连接意见 AND fan_id = 11

关于如何解决此问题或更实用的替代方法的任何想法?

感谢您的帮助。

编辑

对于任何未来的读者,解决方案如下:

class User
  has_many :fans, foreign_key: "fan_id", class_name: "Opinion", dependent: :destroy
end

class Share
  has_many :opinions, foreign_key: "like_id", dependent: :destroy
  has_many :likes, through: :opinions
  has_many :fans, through: :opinions
end

SharesController 和 Opinion 模型保持不变。

【问题讨论】:

  • 我并没有真正了解您在 Share 类中的所有关联的目的,而且您正在引用 MicroPost 类,但您没有显示该类的代码。您能否用简单的英语解释一下您的模型之间的关系是什么?
  • 这行有点奇怪:has_many :agreeables, foreign_key: "fan_id", class_name: "Opinion", dependent: :destroy。这条线将使如果您执行share.agreeables,它将查找fan_id == share.id 的意见。但是你说 fan_id 应该是用户 id。
  • pjam,很抱歉我修复了不正确的数据。基本上我的目标是,当您单击用户帖子(共享)上的链接时,它将显示谁“喜欢”了该帖子。 Hense has_many 喜欢。这已经是一种工作方法,我只想能够显示哪些用户喜欢该分享。对困惑感到抱歉。杰斯珀,也许这就是问题所在。我实际上不是在寻找 share.agreeables 而是 share.fans (我想这会产生相同的结果?我需要从这个模型中排除粉丝线吗?如果是这样,它应该包含在 User 模型中吗?

标签: ruby-on-rails ruby-on-rails-3 foreign-keys nested-attributes has-many-through


【解决方案1】:

如果你想得到所有喜欢Share的用户,下面的代码应该足够了:

class User
  has_many :opinions, foreign_key: "fan_id", dependent: :destroy
  has_many :shares, through: :opinions
end

class Share
  has_many :opinions, foreign_key: "like_id", dependent: :destroy
  has_many :fans, through: :opinions # I'm not sure, but you might need to add class_name option here
end

class Opinion
  belongs_to :fan, class_name: "User"
  belongs_to :like, class_name: "Share"
end

在您的控制器中, @shares = @share.fans.paginate(page: params[:page]) 将返回用户(粉丝)列表

编辑:由于您没有使用传统名称(粉丝而不是用户,喜欢而不是分享),您可能需要添加更多选项,例如 inverse_of 和 class_name,但我不太确定

【讨论】:

  • 谢谢!这看起来很有希望,但只有一个问题。我已经在我的用户模型中定义了 has_many :shares 并且我的共享表有 user_id。有什么解决方法吗?
  • 我不清楚你在这里问什么,但你可以编写一个新的迁移,例如删除无用的 user_id 列。
  • 好的,我会试试这个。我假设意见表中的 fan_id 列就足够了?谢谢,我会尽快试试这个!
  • 是的,fan_id 应该足够了。顺便说一句,我不知道我是否正确,但我通常会尝试依赖rails约定进行命名。在您的代码中,这将是命名 opinions 表中的列 user_idshare_id 然后您始终可以为方法命名为您想要的名称,例如 likefans
  • 我在尝试应用这些建议的方法时查看了我的代码,并意识到我一定没有正确解释某些内容,因为我相信您误解了。当用户“喜欢”一个共享时,他们将作为 fan_id 插入到意见表中,并且“喜欢的共享”作为“like_id”插入因此我无法创建新的迁移并将 user_id 替换为 fan_id。 @shares.fans 将呈现表中的所有用户。我只想渲染“喜欢的粉丝”(喜欢分享的用户)这有意义吗?我会努力的,但如果你有什么东西请告诉我!谢谢你的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 2014-02-05
  • 1970-01-01
相关资源
最近更新 更多