나는 rails-settings 보석을 사용하고의 사용을 이해하려고 노력하고, 나는 당신이 (나는 카드 게임에 대한 내 자신의 라이브러리를 짓고 있어요) 액티브 클래스에 기능을 추가하는 방법을 이해하기 위해 노력하고있어, 나는 그이를 발견 보석은 액티브 :: 기본 클래스에 기능을 추가하기 위해 메타 프로그래밍 기술 중 하나를 사용합니다 (I 루비에서 마스터 메타는 프로그래밍에서 멀리 해요,하지만 난 그것을 배우려고 노력하고있어)는 class_eval
module RailsSettings
class Railtie < Rails::Railtie
initializer 'rails_settings.initialize', :after => :after_initialize do
Railtie.extend_active_record
end
end
class Railtie
def self.extend_active_record
ActiveRecord::Base.class_eval do
def self.has_settings
class_eval do
def settings
RailsSettings::ScopedSettings.for_thing(self)
end
scope :with_settings, :joins => "JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}')",
:select => "DISTINCT #{self.table_name}.*"
scope :with_settings_for, lambda { |var| { :joins => "JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}') AND
settings.var = '#{var}'" } }
scope :without_settings, :joins => "LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}')",
:conditions => 'settings.id IS NULL'
scope :without_settings_for, lambda { |var| { :joins => "LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}') AND
settings.var = '#{var}'",
:conditions => 'settings.id IS NULL' } }
end
end
end
end
end
end
무엇 왜 그가 ActiveRecord :: Base 클래스를 열고 함수를 정의한다면 ActiveRecord :: Base에 class_eval을 사용하는 것이 이해가 안된다. 전과 (
module ActiveRecord
class Base
def self.has_settings
class_eval do
def settings
RailsSettings::ScopedSettings.for_thing(self)
end
scope :with_settings, :joins => "JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}')",
:select => "DISTINCT #{self.table_name}.*"
scope :with_settings_for, lambda { |var| { :joins => "JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}') AND
settings.var = '#{var}'" } }
scope :without_settings, :joins => "LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}')",
:conditions => 'settings.id IS NULL'
scope :without_settings_for, lambda { |var| { :joins => "LEFT JOIN settings ON (settings.thing_id = #{self.table_name}.#{self.primary_key} AND
settings.thing_type = '#{self.base_class.name}') AND
settings.var = '#{var}'",
:conditions => 'settings.id IS NULL' } }
end
end
end
end
내가 두 번째 class_eval을 이해 :이 같은
뭔가 특별히 블록의 동적 아무 것도 없다는 것을 (당신이 변수를 포함하는 문자열에 class_eval 또는 instance_eval 할 때 내가 동적 의미하는 것은) def 설정)은 'has_settings'가 맞는 모든 클래스에서 즉석에서 함수를 정의하는 것입니다. 같은 질문을 던지면 "class_eval .... def settings"대신 "def self.settings"를 사용할 수 있다고 생각합니다.
당신은 내가, 그것이 좋은 연습을 알고 내 질문을 asnwer하지 않았고 즉, 두 번째 class_eval에 의해 그냥 "데프 설정"전에 하나를 볼 벌 수 있지만, 내 질문은 나 개방을 사용하여 첫 번째 class_eval에 대해이었다 그 수업에는 같은 효과가 없다고? – kalbasit
@eMxyzptlk : 메서드 내에서 "클래스 xyz"를 수행한다는 의미입니까? – tokland
@eMxyzptlk : 루비는 ("메소드 본문에서 클래스 정의"오류) : 허용하지 않습니다 나는 그냥 온 디맨드 방식 정의의 또 다른 레벨을 추가 생각합니다. 대신 액티브 자체의 Railtie에 이러는함으로써, 명시 적으로 다시 명시 적으로 요청하는 경우'settings'을 정의하는 옵션을 제공하는 요청 될 때까지 심지어 액티브에'has_settings'를 추가하지 않고이 라이브러리를 필요로하는 것이 가능하다. –