2011-12-12 105 views
2

我已经定义了以下两个作用域和两个工作罚款:联盟NoMethodError(未定义的方法`default_scoped“......?)

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。我认为default_scope?方法已在导轨3被移除*,但它抱怨说......

谁能帮助?

回答

3

有在Rails的union没有这样的方法(我不知道阿雷尔)。就像你通常那样构建范围。

编辑: 您可以在作用域定义中始终使用raw 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

阿雷尔提供阿雷尔::节点:联盟和发现了一些例子使用联盟()方法,所以我想有一个。无论如何,我不知道如何设计朋友范围以正常方式返回其他范围的联合。 – Scholle

+0

你可以随时使用原始的SQL的范围定义(我想这将是办法,如果你想在联盟) – maprihoda

+0

看到我的最新答案 – maprihoda

3

default_scope?确实从Rails 3和更高版本中删除。 我不知道为什么这个错误弹出(我有同样的问题),但在使用范围似乎union()无法工作。直接使用他们(外scope)似乎工作:

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

就个人而言,我不把工会的范围,并直接使用它(幸运的是我只有我们这一个地方,所以对我来说是不是一个大不了)。

我也不能直接与find()first()all(),等我想arel尚未完成使用union() ...为了规避这个问题,我使用:

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

但也许/大概有更好的方法来防止这种...? (如等待AREL更新:P)

+0

应当指出的是,自2012年以来这个问题一直是开放的阿雷尔,仍然是打开。我不希望很快就会有修复。 –

+1

可能的https://github.com/brianhempel/active_record_union宝石的帮助,它定义在'的ActiveRecord :: Query''union'返回'的ActiveRecord :: Query'? –

相关问题