Ruby on rails 问题是我看到了一个我没有明确定义的应用范围。魔法范围似乎是基于我正在构建的父“主”对象。查询的隐式范围为:从“items”中选择“items”。*其中“items”。“master_id”=980190963[…]。根据你目前的回答,我还不明白为什么这个范

Ruby on rails 问题是我看到了一个我没有明确定义的应用范围。魔法范围似乎是基于我正在构建的父“主”对象。查询的隐式范围为:从“items”中选择“items”。*其中“items”。“master_id”=980190963[…]。根据你目前的回答,我还不明白为什么这个范,ruby-on-rails,Ruby On Rails,问题是我看到了一个我没有明确定义的应用范围。魔法范围似乎是基于我正在构建的父“主”对象。查询的隐式范围为:从“items”中选择“items”。*其中“items”。“master_id”=980190963[…]。根据你目前的回答,我还不明白为什么这个范围突然出现。我正在寻找一个解释,解释为什么当我在其他地方看不到它时,这个作用域就应用在关联块中。对不起,当你调用m.items时,你没有看到它吗?这就是应用这个范围的原因。是的,但我不明白为什么要应用这个范围。如果在块之外使用m.items,则


问题是我看到了一个我没有明确定义的应用范围。魔法范围似乎是基于我正在构建的父“主”对象。查询的隐式范围为:
从“items”中选择“items”。*其中“items”。“master_id”=980190963[…]
。根据你目前的回答,我还不明白为什么这个范围突然出现。我正在寻找一个解释,解释为什么当我在其他地方看不到它时,这个作用域就应用在关联块中。对不起,当你调用m.items时,你没有看到它吗?这就是应用这个范围的原因。是的,但我不明白为什么要应用这个范围。如果在块之外使用m.items,则没有作用域。是否有文档中的解释解释了为什么在关联块中应用范围?否则它不会应用范围是什么意思?尝试执行m.items.to_sql。根据定义,m.items是items.where(m_id=m.id)。我认为您需要将其视为一个类方法,在这种情况下,您正在对传入的集合进行操作——在这种情况下,集合(self)是m.items。如果我有一个类方法(self.some_函数)并调用Model.scope_one.scope_two.some_函数,显然self将是Model.scope_one.scope_two。您正在对集合m.items调用build。为了我的理智,我还测试了m.items.other_scope.build,而self是m.items.other_scope,正如预期的那样。
class Master < ApplicationRecord

  has_many :items,  inverse_of: :master do
    def build att=nil
      item = self.new(master: proxy_association.owner)      
      item.description1 = self.where(master_id: nil).to_sql
      item.description2 = self.unscoped.where(master_id: nil).to_sql
      item
    end
  end

end
class Item < ApplicationRecord
  belongs_to :master

  before_create -> {
    self.description1 = self.class.where(master_id: nil).to_sql
    self.description2 = self.class.unscoped.where(master_id: nil).to_sql
  }

end
require 'test_helper'

class MasterTest < ActiveSupport::TestCase

  test "master build outside association works as expected" do

    m = Master.create! name: 'Bob'
    item = Item.create master: m, name: 'Wall'

    puts "Master: #{m}"
    puts "self.where(master_id: nil).to_sql"
    puts item.description1
    puts "self.unscoped.where(master_id: nil).to_sql"
    puts item.description2

    # Flawed understanding would expect the queries to be the same
    assert item.description1 == item.description2
  end

  test "master association blocks add an unexpected scope" do

    m = Master.create! name: 'Bob'
    item = m.items.build name: 'Wall'

    puts "Master: #{m}"
    puts "self.where(master_id: nil).to_sql"
    puts item.description1
    puts "self.unscoped.where(master_id: nil).to_sql"
    puts item.description2

    # Flawed understanding would expect the queries to be the same
    assert item.description1 == item.description2
  end
end
Master: #<Master:0x0055c3ee11b770>
self.where(master_id: nil).to_sql
SELECT "items".* FROM "items" WHERE "items"."master_id" = 980190963 AND "items"."master_id" IS NULL
self.unscoped.where(master_id: nil).to_sql
SELECT "items".* FROM "items" WHERE "items"."master_id" IS NULL
m = Master.create! name: 'Bob'
item = m.items.build name: 'Wall'

puts "Master: #{m}"
puts "self.where(master_id: nil).to_sql"
puts item.description1
puts "self.unscoped.where(master_id: nil).to_sql"
puts item.description2

# Flawed understanding would expect the queries to be the same
assert item.description1 == item.description2
item = m.items.build name: 'Wall'
item.description1 = self.where(master_id: nil).to_sql
Item.where(master_id: m.id).where(master_id: nil).to_sql
self.unscoped.where(master_id: nil).to_sql
m.items
self.to_sql