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