Ruby on rails 3 Arel、联接和Rails查询

Ruby on rails 3 Arel、联接和Rails查询,ruby-on-rails-3,join,arel,Ruby On Rails 3,Join,Arel,最近有一段时间我遇到了一个问题,我找到了去Arel的路,看起来它应该允许我在我的查询中做或做 作为起点,我需要将现有的Rails 3查询转换为Arel,这就是我遇到问题的地方 下面的范围和查询按照我的预期工作。它给出了与特定用户广告相关的请求 #in the Request class scope :responder, lambda { |user| joins(:ad).where(:ads => { :user_id => user }) } Request.responde

最近有一段时间我遇到了一个问题,我找到了去Arel的路,看起来它应该允许我在我的查询中做或做

作为起点,我需要将现有的Rails 3查询转换为Arel,这就是我遇到问题的地方

下面的范围和查询按照我的预期工作。它给出了与特定用户广告相关的请求

#in the Request class
scope :responder, lambda { |user| joins(:ad).where(:ads => { :user_id => user }) }

Request.responder(303).to_sql

=> "SELECT \"requests\".* FROM \"requests\" INNER JOIN \"ads\" ON \"ads\".\"id\" = \"requests\".\"ad_id\" WHERE (\"ads\".\"user_id\" = 303)"
根据Arel github页面上的doco和Railscast 215,我应该能够执行以下操作来使用Arel复制查询

  requests = Request.arel_table
  ads = Ad.arel_table
  where(requests.join(ads).on(ads[:id].eq(requests[:ad_id])))
这会导致一个错误

TypeError: Cannot visit Arel::SelectManager
不过,我可以在控制台中执行以下操作

r = Request.arel_table
a = Ad.arel_table

r.join(a).to_sql
 => "SELECT  FROM \"requests\" INNER JOIN \"ads\" "
所以它看起来像是在形成SQL请求,但是当你把它放在一个where中时

Request.where(r.join(a)).to_sql
我得到以下信息

TypeError: Cannot visit Arel::SelectManager....
我尝试过在where and it works中执行其他Arel操作(例如)

这超出了我对rails/ruby不断增长的了解。有什么想法吗


提前感谢。

我不是Arel专家,但我认为您希望合并联接和where范围,而不是将一个范围包含在另一个范围内。所以不是

where(requests.join(ads).on(ads[:id].eq(requests[:ad_id])))
尝试(例如):


要在rails 3中执行或,请查看MetaWhere。上面有一个很好的railscast:

这里更大的答案是,尽管这里有一个奇特的、鼓舞人心的例子:

…Active Record实际上不支持全部Arel功能。至少,不是通过关系或范围。您可以在Arel中创建任何(大多数)查询,但最终您将使用:

sql = User.arel_table.(something awesome in Arel).to_sql
users = User.find_by_sql(sql)
从技术上讲,仍然有一个“.to_a”方法,但它不返回ActiveRecord模型实例,并且已弃用

{UPDATE}


是ActiveRecord有史以来发生的最好的事情。所有这些阿雷尔的东西都实现了。

到目前为止,我找到的最灵活的解决方案如下:

class Request
  class << self
    def your_join_scope
      joins('INNER JOIN "ads" ON "ads"."id" = "requests"."ad_id"')
    end
  end
end
类请求

class您可以使用
join\u sources。首先在
Arel::SelectManager
上使用
join\u sources

requests = Request.arel_table
ads = Ad.arel_table
Request.joins(requests.join(ads).on(ads[:id].eq(requests[:ad_id])).join_sources.first)

谢谢DGM。我见过MetaWhere,但我试图避免添加另一个gem,因为rails中似乎已经有了一些工具。不过我应该再看看。谢谢你。我会试一试。如果你在末尾加一个“.to_-sql”并把它放在
请求中,那就行了。通过
sql(…)
查找\u无需使用Arel::SqlLiteral为什么不直接加入(““广告”上的“内部加入”广告“.id”=“请求”。“ad_-id”)你的wordpress链接死了我知道!但在2011年初,这是一个非常好的链接。我很难过,他不再炫耀这个项目了。archive.org链接到僵尸博客:你也可以做
join\u sources
joins会找到答案的。我相信如果你有多个,也会通过所有的考试,但不要在第二部分引用我的话
class Request
  class << self
    def your_join_scope
      joins('INNER JOIN "ads" ON "ads"."id" = "requests"."ad_id"')
    end
  end
end
requests = Request.arel_table
ads = Ad.arel_table
Request.joins(requests.join(ads).on(ads[:id].eq(requests[:ad_id])).join_sources.first)