Ruby on rails 定义动态类方法

Ruby on rails 定义动态类方法,ruby-on-rails,ruby,Ruby On Rails,Ruby,我知道这个问题已经被问过好几次了,但我认为在这种情况下永远不会 我尝试为我的模型创建一个“帮助器”(一个作为),用于根据状态id自动设置状态 acts_as_statusable :status, [ :in_progress, closed ] 此帮助程序创建方法status,status=(sym),进行中?,关闭?和命名作用域进行中和关闭 我的助手工作,这是它放在lib/ class ActiveRecord::Base def self.acts_as_statusable(*ar

我知道这个问题已经被问过好几次了,但我认为在这种情况下永远不会

我尝试为我的模型创建一个“帮助器”(一个
作为
),用于根据状态id自动设置状态

acts_as_statusable :status, [ :in_progress, closed ]
此帮助程序创建方法
status
status=(sym)
进行中?
关闭?
和命名作用域
进行中
关闭

我的助手工作,这是它放在
lib/

class ActiveRecord::Base
  def self.acts_as_statusable(*args)
    field_name = args.first
    field_name_id = :"#{field_name}_id"
    statuses = args.second

    # Define getter
    define_method(field_name) do
      return nil if self.send(field_name_id).nil?
      return statuses[self.send(field_name_id)]
    end

    # Define setter
    define_method(:"#{field_name}=") do |v|
      return self.send(:"#{field_name_id}=", statuses.index(v))
    end

    # Define a status? for each status,
    # and a named scope .status
    statuses.each do |status|
      define_method(:"#{status}?") do
        return self.send(field_name) == status
      end
      scope status, -> { where(["#{table_name}.#{field_name_id} = ?", statuses.index(status)]) }
    end

    validates field_name_id, :inclusion => { :in => (0...statuses.length).to_a }
  end
end
现在,问题来了

我需要有一个类方法,对于每个使用
作为\u statusable
的类,名为
status\u index(sym)
,它从状态返回状态id

问题是,我找到的每个定义类模型的解决方案都使用了
Module
extend
intent
,但我无法将
actions as\u statusable
行的
status变量插入到这个模块中


我该怎么做?我使用Rails 4。

您可以使用
class\u eval
class\u variable\u set

class_variable_set :"@@#{field_name}_options", statuses

class_eval <<-RUBY
  def self.status_index(sym)
    @@#{field_name}_options.index(sym)
  end
RUBY
class_变量集:“@@{field_name}\u选项”,状态

class_eval您可以使用
class_eval
class_变量集

class_variable_set :"@@#{field_name}_options", statuses

class_eval <<-RUBY
  def self.status_index(sym)
    @@#{field_name}_options.index(sym)
  end
RUBY
class_变量集:“@@{field_name}\u选项”,状态

class\u evalxlembouras-您的解决方案非常有效!我有两种型号:

class User < ActiveRecord::Base
  acts_as_statusable :status, [ :little, :big ]
end 

class Price < ActiveRecord::Base
  acts_as_statusable :status, [ :in_progress, :closed ]
end
我修改了该结构,并使用了由编写的代码。 Rails 4,ActiveSupport::使用了关注点

lib/active\u record\u extension.rb:

module ActiveRecordExtension
  extend ActiveSupport::Concern  
end
ActiveRecord::Base.send(:include, ActiveRecordExtension)
require "active_record_extension"
config/initializers/extensions.rb:

module ActiveRecordExtension
  extend ActiveSupport::Concern  
end
ActiveRecord::Base.send(:include, ActiveRecordExtension)
require "active_record_extension"
config/initializers/active\u record\u monkey\u patch.rb

class ActiveRecord::Base     
  def self.acts_as_statusable(*args)
    ...
    # ForgetTheNorm's CODE..
    ...
    # xlembouras CODE:
    class_variable_set :"@@#{field_name}_options", statuses

    class_eval <<-RUBY
      def self.status_index(sym)
        @@#{field_name}_options.index(sym)
      end
    RUBY
  end
end
class ActiveRecord::Base
定义自身作为可状态(*args)
...
#忘记密码。。
...
#xlembouras代码:
类变量集:“@@{field\u name}\u options”,状态

class\u evalxlembouras-您的解决方案非常有效!我有两种型号:

class User < ActiveRecord::Base
  acts_as_statusable :status, [ :little, :big ]
end 

class Price < ActiveRecord::Base
  acts_as_statusable :status, [ :in_progress, :closed ]
end
我修改了该结构,并使用了由编写的代码。 Rails 4,ActiveSupport::使用了关注点

lib/active\u record\u extension.rb:

module ActiveRecordExtension
  extend ActiveSupport::Concern  
end
ActiveRecord::Base.send(:include, ActiveRecordExtension)
require "active_record_extension"
config/initializers/extensions.rb:

module ActiveRecordExtension
  extend ActiveSupport::Concern  
end
ActiveRecord::Base.send(:include, ActiveRecordExtension)
require "active_record_extension"
config/initializers/active\u record\u monkey\u patch.rb

class ActiveRecord::Base     
  def self.acts_as_statusable(*args)
    ...
    # ForgetTheNorm's CODE..
    ...
    # xlembouras CODE:
    class_variable_set :"@@#{field_name}_options", statuses

    class_eval <<-RUBY
      def self.status_index(sym)
        @@#{field_name}_options.index(sym)
      end
    RUBY
  end
end
class ActiveRecord::Base
定义自身作为可状态(*args)
...
#忘记密码。。
...
#xlembouras代码:
类变量集:“@@{field\u name}\u options”,状态

class\u eval您是否尝试过定义\u singleton\u方法?我没有得到您想要的
status\u index(sym)
操作。你能举个例子吗?为什么不简单地使用状态机呢?也许我误解了这个问题,但对我来说,这就像是重新发明轮子。你尝试过定义单例方法吗?我没有得到你想要的
status\u index(sym)
。你能举个例子吗?为什么不简单地使用状态机呢?也许我误解了这个问题,但对我来说,这就像是重新发明了wheelnice概念证明Nice概念证明concept@xlembouras谢谢工作完美。“我还没想过呢!”谢谢!工作完美。我没想过。