【问题标题】:Combining custom joins with regular rails joins将自定义连接与常规导轨连接相结合
【发布时间】:2011-04-07 02:17:58
【问题描述】:

我有这样的模型 foo、bar 和 baz

# has a field join_condition_string
class Foo < AR::Base
    :has_many :bar
end

# Has a field exclusion_critera
class Bar < AR::Base
    :belongs_to foo
end

# has a fields condition_string, exclusion_criteria
class Baz < AR::Base
end

我希望能够根据 Bar 和 Baz 的标准检索 Foo。因此,我需要加入这两个模型。我想用 Rails 魔法加入 Bar,

Foo.find(:all, :joins => :bar)

我想使用自定义加入加入 Baz。

Foo.find(:all, :joins=>"left join baz on baz.condition_string = foo.join_condition_string")

这些单独工作很好,但我似乎无法找到优雅地组合它们的方法。

我尝试做一些幼稚的事情并将这两个条件组合在一个数组中,但无济于事。

Foo.find(:all, :joins=>["left join baz ...", :bar])

docs 声称我可以做到 Foo.find(:all, :joins =&gt; :bar, :joins =&gt; "left join baz ..."),但这似乎不应该工作(而且它在 rails 2.3.8 中也没有),因为要查找的 args 被包裹在一个散列中并且第一个 :joins 丢失了。

当然,我总是可以将两者组合成一个 :joins 字符串。但是,如何将这两个调用与尽可能少的原始 sql 结合起来呢?有什么想法吗?

编辑:接受的答案确实回答了我的问题,但我仍然认为可能有更好的方法。

编辑 2:正如 ruby​​prince 所说,这已在 rails >= 3.0.0 中解决

【问题讨论】:

  • 你试过这个Foo.find(:all, :joins=&gt;[:bar, "left join baz ..."])吗?我的意思是数组倒序...

标签: ruby-on-rails ruby activerecord rails-activerecord


【解决方案1】:

这可能是解决您的问题的方法。您可以将这些连接作为模型中的 2 个命名范围单独保留,并像这样调用它们。

class Foo < AR::Base
  has_many :bars
  named_scope :joined_bars, :joins => :bars
  named_scope :joined_baz, :joins => "LEFT JOIN baz on ..."
end

然后你可以像这样在控制器中调用它

Foo.joined_bars.joined_baz

您可以像这样将任何条件或其他参数附加到所选对象

Foo.joined_bars.joined_baz.all(:conditions => ..,
                               :limit => ..)

这将创建一个包含所有连接、位置、限制等的 SQL 查询。

【讨论】:

  • 这肯定行得通,但如果有更好的解决方案,那就了。实际上,joined_bars 是一个非常复杂的连接哈希 {:model=>{:nother_model=>:etc},添加范围会给已经很大的模型添加不必要的混乱。
  • 你写它的方式应该可以工作,但我认为这是 Rails 中的一个错误。
  • @CarlitosMorales。如果你的 Rails >=3,你不必做这一切。它有Foo.joins(:bar).joins("LEFT JOIN baz on ...")
  • 没关系,我找到了我想要的 sintaxis =)
猜你喜欢
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
相关资源
最近更新 更多