11

Rails 3+ のスコープに関する素晴らしい記事を見つけました: http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-before -named-scope/index.html

次のように、異なるモデルのスコープをマージすることが可能であることを (「クレイジー タウン」セクションで) 読むことができます。

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にしました、そして今私は得ます:

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>'

==>もう機能しません。

スコープのマージはすばらしかったのに、今は思ったほど DRY になれないので、それは私を悲しくさせます。

あなたは知っていますか :

  • 2 つのバージョンの間で何が起こったのですか?
  • 同じことをする他の方法はありますか?
4

1 に答える 1

17

メソッドはもう&機能していないようです (残念ながら、構文がきちんとしていることに気付きました)。次のように置き換えることができます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.

誰かが興味を持っている場合に備えて、それを廃止するコミットは次のとおりです

于 2011-10-05T12:30:13.163 に答える