Tag: 元编程

ROR:Workflow gem:我想从数据库实现动态状态

我正在研究一个必须实现动态工作流的项目。 动态 :我将工作流的状态存储在名为wf_steps的数据库表中,工作流gem必须从数据库为特定工作流创建states 为此,我试图使用工作流gem 。 您可以在gem的github-page中看到它如何初始化状态和相应的事件。 我的代码: class SpsWorkflow < ActiveRecord::Base belongs_to :user has_many :wf_steps include Workflow workflow do # binding.pry # read wf-states from the database # for now let event be same for all the states self.wf_steps.each do |step| state step.title.to_sym do event :assign, transitions_to: :assigning event :hire, transitions_to: :hiring event :not_hire, transitions_to: […]

在实施“副作用”元编程时加载类的麻烦

我正在使用Ruby on Rails 3.2.9和Ruby 1.9.3-p125。 方案如下: 我实现了一个acts_as_customizable插件,我有一个Article模型类“充当可自定义”。 该插件通过元编程, 将一个名为customize 的方法添加到Comment模型类中( 注意 :由于这个原因,该插件具有副作用,因为操作了Article对象范围之外的Comment对象)。 鉴于这种情况,当我(重新)启动服务器并运行@comment.customize我得到错误NoMethodError – undefined method ‘customize’ for # 。 但是,当我(重新)启动服务器并运行以下代码时,所有工作都按预期工作: Article @comment.customize 如果我理解“邪恶”部分,上面的代码是有效的,因为在运行customize方法之前对Article类的“简单”调用使得它触发acts_as_customizable方法,该方法又将(通过元编程) customize方法添加到Comment类。 我该如何避免“邪​​恶”?

如何在rails中创建动态属性别名?

在类定义中,我得到了一个我想要返回的属性列表而不是数据库的值,除非这些值的存储容器是nil: class Label < ActiveRecord::Base CONFIRM_DATA = ["attr1", "attr2"] # "attr1", "attr2" is database fields CONFIRM_DATA.each do |att| alias_attribute "original_#{att}".to_sym, att.to_sym define_method att.to_sym do temp_attr_store[ att.to_sym ] || read_attribute( "original_#{att}".to_sym) end end end 如您所见,我尝试在temp_attr_store存储temp_attr_store一些临时值:它们应该出现而不是db值,并希望影响对象的关联。 上面的代码不起作用,所有attr1访问结果都是零。 谢谢!

如何使用元编程干?

似乎应该有一个很好的方式通过MP来干这个: class Dashboard def self.num_registrations_past_day return User.recent_registrations(24.hours.ago).count end def self.num_registrations_past_three_days return User.recent_registrations(3.days.ago).count end def self.num_registrations_past_seven_days return User.recent_registrations(7.days.ago).count end def self.num_registrations_past_month return User.recent_registrations(30.days.ago).count end def self.avg_registrations_past_three_days return (self.num_registrations_past_three_days / 3.to_f) end def self.avg_registrations_past_seven_days return (self.num_registrations_past_seven_days / 7.to_f) end def self.avg_registrations_past_month return (self.num_registrations_past_month / 30.to_f) end def self.total_registered_users return User.count end def self.total_activated_users return User.total_activated end end

如何在不编辑gem源的情况下向ruby gem添加方法?

我正在使用acts_as_taggable_on gem并想在其中一个gem源文件( tag.rb )中添加一个方法,但我不想以任何方式更改gem源。 我已经尝试在/app/models目录或/lib目录中创建我自己的tag.rb文件,然后将期望的方法添加到该文件,期望ruby将合并两个tag.rb文件 但是当我这样做时,我得到一个NoMethodError: undefined method …… 我错过了什么?

如何在模块中对类方法进行别名?

我正在使用Ruby v1.9.2和Ruby on Rails v3.2.2 gem。 我有以下模块 module MyModule extend ActiveSupport::Concern included do def self.my_method(arg1, arg2) … end end end 我想为类方法 my_method添加别名。 所以,我说了以下( 不工作 )代码: module MyModule extend ActiveSupport::Concern included do def self.my_method(arg1, arg2) … end # Note: the following code doesn’t work (it raises “NameError: undefined # local variable or method `new_name’ for #”). […]

重新打开由gem提供的ActiveRecord模型

我正在尝试扩展gem( https://github.com/peteonrails/vote_fu )为我的应用程序提供的ActiveRecord模型( Vote )。 (即app/models没有vote.rb ) 我的第一个方法是创建一个名为lib/extend_vote.rb的文件,其中包含以下代码: Vote.class_eval do after_create :create_activity_stream_event has_one :activity_stream_event def create_activity_stream_event # something.. end end 这在创建第一个投票时有效,但是当我尝试创建每个后续投票时,我得到错误TypeError (can’t dup NilClass) 。 我认为这个错误是由于每次请求后自动重新加载Vote类这一事实,但是lib/extend_vote.rb的代码只在服务器启动时加载一次,这会导致has_one :activity_stream_event关联表现得很奇怪。 (另外,如果我在development.rb设置config.cache_classes = true ,问题就会消失) 为了解决这个问题,我尝试通过向to_prepare添加to_prepare块来对每个请求重新加载投票扩展: config.to_prepare do load ‘extend_vote.rb’ end 这解决了(can’t dup NilClass)问题,但现在每当我创建新的投票时, create_activity_stream_event回调都被称为额外的时间。 即,第一次投票调用一次,第二次投票两次,等等。所以看起来to_prepare块正在积极地重新加载扩展TOO并添加重复的回调。 向此Vote模型添加方法和回调的最佳方法是什么?

Ruby无法覆盖send方法

这有点难以解释,但我似乎偶尔无法覆盖我的应用程序中的’send’方法。 我正在基于EventMachine创建一个相当大的应用程序,有时,在我的代码的深处,我决定在我的一个类中定义一个’send’方法。 当我稍后尝试使用此方法时,我通常会得到类似TypeError: is not a symbol ,例如以下(恰好是由所需的AMQP gem(不是我的)引起的,但是这个问题更一般): Exception caught: TypeError – # is not a symbol /Users/mlartz/.rvm/gems/ruby-1.9.2-p180@rflow-component-devel/gems/amq-client-0.7.0.alpha27/lib/amq/client/queue.rb:137:in `bind’ /Users/mlartz/.rvm/gems/ruby-1.9.2-p180@rflow-component-devel/gems/amqp-0.8.0.rc12/lib/amqp/queue.rb:282:in `block in bind’ /Users/mlartz/.rvm/gems/ruby-1.9.2-p180@rflow-component-devel/gems/eventmachine-1.0.0.beta.3/lib/em/deferrable.rb:47:in `call’ /Users/mlartz/.rvm/gems/ruby-1.9.2-p180@rflow-component-devel/gems/eventmachine-1.0.0.beta.3/lib/em/deferrable.rb:47:in `callback’ 这是违规行: @connection.send(Protocol::Queue::Bind.encode(@channel.id, @name, exchange_name, routing_key, nowait, arguments)) 在这种特殊情况下,@ @connection对象的类定义了一个接收AMQ::Protocol::MethodFrame的send方法。 但是,似乎以某种方式调用了默认的Object#send方法(它需要一个符号,因此是exception)。 在开发早期,我在我的一个自定义类上遇到了同样的问题,通过将“send”方法的名称更改为“send_message”解决了这个问题。 所以,由于这有点笼统,问题是,什么样的事情可能会干扰我在定义它的对象上调用自定义定义的send方法的能力? 仅供参考:我在OSX上使用Ruby 1.9.2p180。

动态获取/设置参数的默认值

从以下场景开始: class Foo def bar(baz={}) p baz end end foo = Foo.new p meth = foo.method(:bar) # => # p meth.parameters # => [[:opt, :baz]] 所以我可以弄清楚方法bar是可选的,但是如何找到该方法的默认值( {} )?

Ruby方法查找是从类的底部开始并从上到下,从顶部开始向下运行吗?

我开始了解有关Ruby对象模型的更多信息,并试图了解方法的流程。 据我所知,一个对象通过检查它的自我类(向右)来搜索一个方法,如果在那里找不到该方法,它就会上升到祖先层次结构。 我感到困惑的是……当它看到一个类时,它是从下到上还是从上到下读取每个方法? 我在想前者。 但如果这是真的,那么它让我觉得与我自己总是理解的关于如何读取/解释程序的行为相反 – 从上到下。 有人可以证实我对此的理解。 谢谢。