Я думаю, что этого невозможно достичь, потому что контекст, в котором выполняется процедура, отличается в зависимости от того, как он вызывается. Я сделал базовое приложение для ваших моделей, и вот что происходит, когда вы вызываете различные методы ( ap is ):
class School < ActiveRecord::Base
has_many :students, :conditions => proc { ap self; "year_id=#{send(:active_year_id)}" }
end
Когда вы вызываете отношение учеников из школьного экземпляра, контекстом процесса является заданный экземпляр School
, поэтому он отвечает на метод active_year_id
[31] pry(main)> School.first.students
School Load (0.2ms) SELECT "schools".* FROM "schools" LIMIT 1
#<School:0x007fcc492a7e58> {
:id => 1,
:name => "My school",
:active_year_id => 1,
:year_id => 1,
:created_at => Tue, 08 May 2012 20:15:19 UTC +00:00,
:updated_at => Tue, 08 May 2012 20:15:19 UTC +00:00
}
Student Load (0.2ms) SELECT "students".* FROM "students" WHERE "students"."school_id" = 1 AND (year_id=1)
+----+----------------+-----------+---------+-------------------------+-------------------------+
| id | name | school_id | year_id | created_at | updated_at |
+----+----------------+-----------+---------+-------------------------+-------------------------+
| 1 | My student | 1 | 1 | 2012-05-08 20:16:21 UTC | 2012-05-08 20:16:21 UTC |
| 2 | Second student | 1 | 1 | 2012-05-08 20:18:35 UTC | 2012-05-08 20:18:35 UTC |
+----+----------------+-----------+---------+-------------------------+-------------------------+
2 rows in set
Но когда вы вызываете отношение включений, контекст отличается, и то, что proc получает как self, является Student
классом, поэтому он не отвечает на этот метод, и это вызовет ошибку
[32] pry(main)> School.includes(:students).all
School Load (0.3ms) SELECT "schools".* FROM "schools"
class Student < ActiveRecord::Base {
:id => :integer,
:name => :string,
:school_id => :integer,
:year_id => :integer,
:created_at => :datetime,
:updated_at => :datetime
}
NoMethodError: undefined method `active_year_id' for #<Class:0x007fcc4a6a3420>
from /Users/fabio/.rvm/gems/ruby-1.9.3-p194/gems/activerecord-3.2.3/lib/active_record/dynamic_matchers.rb:50:in `method_missing'
Я думаю, что отношение has_many нельзя использовать с такого рода процессами, в которых используется метод экземпляра экземпляра School. Я думаю, что единственный способ использовать procs как , описанный здесь , - это вычислить некоторое условие во время выполнения, которое не включает методы экземпляра (временные условия, где с данными из несвязанных моделей и т. Д.).
Более того, School.includes(:students).all
в моем примере не может работать, потому что он должен вызывать метод active_year_id
для каждого экземпляра School
(который должен быть получен из базы данных, прежде чем можно будет включить включения), и таким образом исчезает эффект includes
предполагаемого поведения.
Все это действительно, если active_year_id
является вычисляемым методом, определенным в классе School
на основе данных экземпляра. Вместо этого, если active_year_id
- это не метод, а поле (столбец db) класса School
, с которым можно играть , объединяет и области для достижения результата, аналогичного тому, что Вы хотите достичь, но это должно быть закодировано вручную.