简体   繁体   中英

Inherit and override Rails named scopes

Is there any reasonable way to inherit a named scope and modify it in Rails?

In the application on which I'm working, there are a great many models which have a scope named is_readable . Many of these models inherit from a handful of base models. One of the subclasses needs to add some strictures to its is_readable scope, and I want to avoid:

  1. giving the subclass' scope a new name because then the standard is_readable check could not be performed universally
  2. copy-pasting the superclass' scope definition into the subclass because then any future changes to the superclass' scope would not appear in the subclass

If I'm understanding you right (and I might not be), this should work:

Because a scope is really just syntactical sugar for a class method, we can use super in it.

ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
    t.boolean :readable
  end

  create_table :comments, force: true do |t|
    t.boolean :readable 
    t.boolean :active
  end
end

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true 
  scope :is_readable, -> { where(readable: true) }
end

class Post < ApplicationRecord
end

class Comment < ApplicationRecord
  def self.is_readable
    super.where(active: true)
  end
end

class IsReadableTest < Minitest::Test
  def test_scope
    5.times { Post.create!(readable: true) }
    3.times { Comment.create!(readable: false, active: false) }
    2.times { Comment.create!(readable: true, active: true) }

    assert_equal 5, Post.count
    assert_equal 5, Post.is_readable.count
    assert_equal 5, Comment.count
    assert_equal 2, Comment.is_readable.count 
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM