У меня есть древовидная модель, в которой во всех ситуациях, кроме одной , я хочу обрезать результаты, чтобы вернуть только корни.
class Licence < ActiveRecord::Base
default_scope :conditions => { :parent_licence_id, nil }
belongs_to :parent_licence, :class_name => 'Licence'
has_many :nested_licences, :class_name => 'Licence',
:foreign_key => 'parent_licence_id', :dependent => :destroy
end
class User < ActiveRecord::Base
has_many :licences
end
Использование default_scope
выглядело какпрекрасная идея, потому что различным моделям, имеющим ассоциации с License (их около 4), а также любому коду, использующему find (), не нужно будет делать ничего особенного.Причина, по которой это не , является удивительной идеей в том, что область действия по умолчанию также применяется к has_many
, что приводит к тому, что дети никогда не находят.Но has_many
- это место only , которое необходимо вырвать из области видимости, поэтому, если говорить о поведении по умолчанию, я думаю, что default_scope
вполне разумно.
Так есть ли какой-нибудь хороший способ обойти эту конкретную проблему?
Вот тот, который мне не очень нравится, потому что он использует SQL для почти тривиального запроса:
has_many :nested_licences, :class_name => 'Licence', :dependent => :destroy,
:finder_sql => 'SELECT l.* FROM licences l WHERE l.parent_licence_id = #{id}',
:counter_sql => 'SELECT COUNT(l.*) FROM licences l WHERE l.parent_licence_id = #{id}'
АльтернативноЕсть ли способ применить именованную область видимости к ассоциации из модели?например, что-то вроде этого бессмысленного кода:
class Licence < ActiveRecord::Base
named_scope :roots, :conditions => { :parent_licence_id, nil }
belongs_to :parent_licence, :class_name => 'Licence'
has_many :nested_licences, :class_name => 'Licence',
:foreign_key => 'parent_licence_id', :dependent => :destroy
end
class User < ActiveRecord::Base
has_many :licences, :scope => :roots # a :scope option doesn't really exist
end
Я знаю, что я также могу сделать это:
class Licence < ActiveRecord::Base
named_scope :roots, :conditions => { :parent_licence_id, nil }
belongs_to :parent_licence, :class_name => 'Licence'
has_many :nested_licences, :class_name => 'Licence',
:foreign_key => 'parent_licence_id', :dependent => :destroy
end
class User < ActiveRecord::Base
has_many :licences, :conditions => { :parent_licence_id, nil }
end
Но это действительно не очень СУХОЙ.На самом деле необходимость выполнения каждого запроса через Licence.roots.find()
вместо Licence.find()
тоже не очень СУХАЯ, если честно.Он просто просит, чтобы произошла ошибка, когда область не используется.