Rails 4:左连接获取连接模型的值

时间:2013-12-12 12:23:21

标签: sql ruby ruby-on-rails-4

我有3个型号:

class User < ActiveRecord::Base
  has_many :likes, :dependent => :destroy
end

class Movie < ActiveRecord::Base
  has_many :likes, :primary_key => :mid, :foreign_key => :item_id
end

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :movie, :foreign_key => :item_id, :primary_key => :mid
end

除了喜欢电影之外,用户还可以通过 Like Model 更改喜欢的电影的一些样式选项,例如 expand &amp;

# likes
+---------------------------------------+
| user_id | item_id | expanded | pinned |
|---------|---------|----------|--------|
|    1    |    1    |   true   |  true  |
|    1    |    2    |   false  |  true  |
+---------------------------------------+

# movies
+-----------------------+
|  title   | mid | year |
|----------|-----|------|
|  Avatar  |  1  | 2009 |
| Gladiator|  2  | 2000 |
|  Shrek   |  3  | 2001 |
+-----------------------+

在这个例子中,用户喜欢电影“阿凡达”和“阿凡达”。角斗士,在改变电影状态时(expandedpinned)。

现在,当我想在视图中显示所有3部电影时,我想以登录用户的方式显示电影的状态。 (Avatar => expanded & pinned, Gladiator => pinned, Shrek => nothing)

到目前为止,我的解决方案是加载所有电影,然后检查查询每部电影的状态......这导致了太多的查询。

所需的表格如下所示:

+---------------------------------------------------------------+
| user_id | expanded | pinned | item_id / mid |  title   | year |
|---------|----------|--------|---------------|----------|------|
|    1    |   true   |  true  |       1       | Avatar   | 2006 |
|    1    |   false  |  true  |       2       | Gladiator| 2000 |
|   null  |   null   |  null  |       3       | Shrek    | 2001 |
+---------------------------------------------------------------+

我了解该查询应通过includes加入来构建。

                                                                # ( 1 )
movies = Movie.includes(:likes).where(:likes => {:user_id => current_user.id }).references(:likes)

但是当循环播放电影时,我似乎无法获取加入的likes表格的数据,例如expanded州:

movies.each do |m|
  puts m.expanded
  puts m.likes.expanded
end
# => undefined method `expanded' for #ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Like:0x007fae7ea51f48

我似乎无法弄清楚出了什么问题。提前谢谢!

1 个答案:

答案 0 :(得分:3)

我认为Rails在给出解释性异常方面并不是很好,但是你应该尝试理解它们:

# => undefined method `expanded' for #ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Like:0x007fae7ea51f48

因此,此错误告诉您,您认为应该没有方法expanded

NR。这种事情的一个原因是你自己的代码中的错误!

一个优秀的程序员总是考虑他或她做错了什么,所以让我们来看看你的代码:

m.likes.expanded

这里我们有一个类Movie的对象。从您提供的代码中,我们可以看到它has_many喜欢。这就是最后有s的原因。它不是like而是likes。所以它是一个对象列表。在这种情况下,它是从数据库连接的延迟加载的对象数组。在Rails中,这些由ActiveRecord::Associations::CollectionProxy处理。

所以你在那个代理对象的实例上调用expanded,而是想在Like的实例上调用它。

如果你想这样做,你需要迭代这些,或者选择一个相关的,这可能是当前用户所做的。