为啥在 Rails 3.1 上不再使用带有作用域的合并方法?

Posted

技术标签:

【中文标题】为啥在 Rails 3.1 上不再使用带有作用域的合并方法?【英文标题】:Why using merge method with scopes isn't working anymore on Rails 3.1?为什么在 Rails 3.1 上不再使用带有作用域的合并方法? 【发布时间】:2011-12-01 10:20:30 【问题描述】:

我偶然发现了一篇关于 Rails 3+ 范围的精彩文章:http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.html

您可以在此处(在“Crazy Town”部分)阅读到可以像这样合并来自不同模型的范围:

class User < ActiveRecord::Base

  scope :published, lambda 
    joins(:posts).group("users.id") & Post.published
  
end

按预期工作,并允许您这样做:

User.published.to_sql
#=> SELECT users.* FROM "users"
#   INNER JOIN "posts" ON "posts"."author_id" = "users"."id"
#   WHERE (posts.published_at IS NOT NULL AND posts.published_at <= '2010-02-27 02:55:45.063181')
#   GROUP BY users.id

我在我的 Rails 3.1 项目中尝试过这种方法,但显然它不再起作用了。

所以我克隆了这篇文章的 Rails 3.0.0-beta1 项目,从我的眼中看出这些人没有撒谎,事情正在按照他们所说的方式进行。

然后我 3.1'ed 了它,现在我得到了:

ruby-1.9.2-p290 :003 > User.published.to_sql
  User Load (0.3ms)  SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."author_id" = "users"."id" GROUP BY users.id
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE (posts.published_at IS NOT NULL AND posts.published_at <= '2011-10-05 11:45:00.512231')
  User Load (0.1ms)  SELECT "users".* FROM "users" 
NoMethodError: undefined method `to_sql' for []:Array
  from (irb):3
  from /home/jerefrer/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start'
  from /home/jerefrer/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start'
  from /home/jerefrer/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>'
  from script/rails:9:in `require'
  from script/rails:9:in `<main>'

==> 不再起作用了。

这让我很伤心,因为范围合并很棒,现在我不能像我想要的那样干。

你知道吗:

这两个版本之间发生了什么? 还有其他方法可以做到这一点吗?

【问题讨论】:

【参考方案1】:

&amp; 方法看起来不再有效(太糟糕了,我发现语法很简洁)。你可以换成ActiveRecord::Relation#merge:

class User < ActiveRecord::Base

  scope :published, lambda 
    joins(:posts).group("users.id").merge(Post.published)
  
end

编辑

而且它看起来不会回来了,在 rails 3.0.10 中尝试它会给出弃用警告:

DEPRECATION WARNING: Using & to merge relations has been deprecated and will be removed in Rails 3.1. Please use the relation's merge method, instead.

这是弃用它的提交,以防有人感兴趣:https://github.com/rails/rails/commit/66003f596452aba927312c4218dfc8d408166d54

【讨论】:

现在又回到了主分支:github.com/rails/rails/blob/… @charlysisto 这个文件在 v3.1.0 和 master 之间没有变化,你确定它是正确的吗?

以上是关于为啥在 Rails 3.1 上不再使用带有作用域的合并方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 3.1 中为 CoffeeScript 使用选项“--bare”?

为啥 onclick 在 Rails4 和 coffeescript 中的 turbolinks 的第二页请求上不起作用?

为啥预编译资产不再起作用?

Rails 3.1 资产管道 - 为啥我的图像没有为生产进行预编译?

Rails 3.1 指南针和链轮。使困惑

为啥easy-autocomplete在Rails 6上不起作用?