两个范围的联合导致NoMethodError(未定义的方法`default_scoped?'...)

时间:2011-12-12 14:09:50

标签: ruby-on-rails-3 ruby-on-rails-3.1

我定义了以下两个范围并且都正常工作:

scope :regular_friends, lambda { |user| joins{friendships}.where{friendships.user_id.not_in(user)}}
scope :inverse_friends, lambda { |user| joins{inverse_friendships}.where{inverse_friendships.friend_id.not_in(user)}}

我在这里使用squeel(https://github.com/ernie/squeel)并构建自引用关联,其灵感来自(http://railscasts.com/episodes/163-self-referential-association)

基于此,我想定义第三个范围,它将另外两个的结果联合起来:

scope :friends, lambda { |user| User.regular_friends(user).union(User.inverse_friends(user)) }

不幸的是,它不起作用。我得到了:

NoMethodError (undefined method `default_scoped?' for #<Arel::Nodes::Union:0x8249534>):

我在 Rails 3.1.3 。我认为在Rails 3. *中删除了 default_scope?方法,但它正在抱怨...

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

在Rails中没有union这样的方法(我不知道Arel)。只需像平常一样构建范围。

修改: 您始终可以在范围定义中使用原始sql。我不知道你的应用程序的细节(特别是表是如何互连的),所以我不能完全构建查询。不过,查询看起来与此类似:

scope :friends, find_by_sql(%(
  SELECT users.* FROM users INNER JOIN friendships f on f.user_id = users.#{id} WHERE ...
  UNION
  SELECT users.* FROM users INNER JOIN inverse_friendships i on i.friend_id = users.#{id} WHERE ...
)

答案 1 :(得分:3)

确实从Rails 3及更高版本中删除了

default_scope?。 我不知道为什么会弹出这个错误(我有同样的问题),但在范围中使用union()似乎不起作用。直接使用它们(在scope之外)似乎有效:

User.regular_friends(user).union(User.inverse_friends(user))

就个人而言,我不会将联盟放在范围内并直接使用它(幸运的是我只在一个地方使用它,所以对我来说这不是什么大问题。)

我也不能直接使用union() find()first()all()等。我猜arel尚未完成...绕过我使用的这个问题:

sql = User.regular_friends(user).union(User.inverse_friends(user)).to_sql
result = find_by_sql(sql)

但也许/可能有更好的方法来防止这种情况......? (比如等待更新:P)