2011-10-05 8 views
11

tôi stumbled khi một bài báo tuyệt vời về phạm vi on Rails 3+: http://edgerails.info/articles/what-s-new-in-edge-rails/2010/02/23/the-skinny-on-scopes-formerly-named-scope/index.htmlTại sao sử dụng phương thức hợp nhất với phạm vi không hoạt động trên Rails 3.1?

Bạn có thể đọc ở đó (trong phần 'Crazy Town') mà nó có thể kết hợp phạm vi từ các mô hình khác nhau như thế này:

class User < ActiveRecord::Base 

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

hoạt động như mong đợi và cho phép bạn làm:

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 

Tôi đã thử phương pháp này trong dự án Rails 3.1 của tôi và dường như nó không hoạt động nữa.

Vì vậy, tôi đã sao chép dự án Rails 3.0.0-beta1 của bài viết, thấy bằng mắt tôi rằng các chàng trai không nói dối và mọi thứ đang hoạt động theo cách họ nói.

Sau đó, tôi 3.1'ed nó lên, và bây giờ tôi nhận được:

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

==> Không có tác dụng nữa.

Và điều đó làm tôi buồn, bởi vì phạm vi hợp nhất thật tuyệt vời và bây giờ tôi không thể như DRY như tôi muốn.

Bạn có biết:

  • gì đã xảy ra giữa hai phiên bản?
  • Bất kỳ cách nào khác để thực hiện tương tự?

Trả lời

17

Phương pháp & có vẻ không hoạt động nữa (quá tệ, tôi thấy cú pháp gọn gàng). Bạn có thể thay thế nó bằng ActiveRecord::Relation#merge:

class User < ActiveRecord::Base 

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

Sửa

Và có vẻ như nó sẽ không trở lại, cố gắng nó trong đường ray 3.0.10 đưa ra một cảnh báo không chấp nhận:

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. 

Đây là cam kết không dùng nó, trong trường hợp ai đó quan tâm: https://github.com/rails/rails/commit/66003f596452aba927312c4218dfc8d408166d54

+1

Và nó đã trở lại ngay trong nhánh chính: https://github.com /rails/rails/blob/24cc9e5b4f9b729f02d2e0b56265032d08933a41/activerecord/lib/active_record/relation/spawn_methods.rb#L7 – charlysisto

+1

@charlysisto tệp này không thay đổi giữa v3.1.0 và master, bạn có chắc đó là tệp đúng không? –

+0

bạn nói đúng, bị lẫn lộn bằng cách nào đó – charlysisto