English 中文(简体)
重新打开由宝石提供的积极记录模式
原标题:Re-open an ActiveRecord model that s provided by a gem

我试图扩展一个主动记录模式(Vote ),即一个宝石(https://github.com/peteonrails/vote_fu )为我的应用程序提供。 (在 ap/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

当第一次投票创建时, 这有效, 但是当我试图创建每次随后的投票时, 我就会得到错误 < code> TypeError (无法 dup NilClass)

我认为,这一错误是由于以下事实造成的:在每次请求后,Vote 类都会自动重新装入,但是在服务器启动时,只有一次才装入 lib/extend_vote.rb 中的代码,这导致has_one: 活动_ 流_ event 关联行为怪异。 (因此,如果我在 config.cache_ clases= true 中设置 ,问题就会消失。 rb )

为了解决这个问题,我试图通过在我的 development.rb 中添加一个 to_preppare 块来根据每一项请求重新加载投票延期:

config.to_prepare do
  load  extend_vote.rb 
end

这将解决 (t dup NilClass) 问题, 但是现在每当我创建新选票时, create_ actual_ stream_event 回调会被调出一个额外的时间。 第一票一次调用它,第二票调用它两次,等等。 因此似乎 to_ prepare 块正在重新装入扩展 TOO, 并添加重复的回调 。

为此 < code> Vote 模式添加方法和回调的最佳方式是什么?

问题回答

[日期:应当是防止模块多次列入同一类的正确解决办法]

I believe you can use ActiveSupport::Concern to prevent the module being include several times which result by callback called several time. See the example below :

module VotePatch
  extend ActiveSupport::Concern

  included do
    after_create :create_activity_stream_event
    has_one :activity_stream_event
  end

  module InstanceMethods
    def create_activity_stream_event
      #your code here
    end  
  end

end

Vote.send(:include, VotePatch)

提醒一句:这是一个非常古老的宝石(最近一次承诺是3岁),而且从它的外观看,它不会像现在一样用铁路3.x来操作。在铁路3.x引擎中,这样的东西更容易使用。

据我理解,第一种情况下的问题不是投票模式被重新加载(它应该),而是重新加载了 active_stream_event 模式。由于投票模式没有重新加载,因此在重新加载之前,将关联留在 activity_street_event 类的版本上。由于在重新加载之前,铁路会挤出分类,这会引起问题。

用我的这个,试试这个黑客:

#in config/initializers/abstract_vote.rb
AbstractVote = Vote
AbstractVote.abstract_class = true
Object.send :remove_const, :Vote

#in app/models/vote.rb

class Vote < AbstractVote
  after_create :create_activity_stream_event
  has_one :activity_stream_event

  def create_activity_stream_event
  end
end

这是允许你拥有自己的投票阶级 从宝石中继承的阶级。

但再次,我敦促你找到更多最新的东西或自己滚动(宝石只~250条红宝石线)。

(d) 我尝试一下Agmleraod在评论中的建议,但不要用lib来表达,而用“强势”的配置/初始化器/vote.rb

 class Vote
   after_create :create_activity_stream_event
   has_one :activity_stream_event

   def create_activity_stream_event
   # something..
   end
 end

当然,你可以把宝石叉开, 做你的修改 和你的Gemfile的叉式版本连接起来(这是我的首选)。

Adrien Coquio对Agencypoverce::Concerns 有正确的想法,它们是 的铁路扩展模型方法 。他的代码会有效,你应该使用它。

但是,这不会一直有效,因为当铁路公司在文件更改时重新加载您的班级时,它不会重新蒸发 线。 我能找到的唯一解决办法是附加到一个 ActionDispatch 回调中,以确保文件在每页加载后被重新要求:

if Rails.env.development?
  ActionDispatch::Callbacks.to_prepare do
    require_dependency "../../lib/vote_fu_extensions"
  end
end

在制作过程中,或者如果在配置中设置 cache_ classes 为真,你不需要这样做。

Your issue might be due to the fact that you are monkey patching the class. When rails tries to reload the constants it is not considering your file.

尝试使用以下给出的模块技术 。

添加名为 lib/vote_fu_extension.rb 的文件

module VoteFuExtension
  def self.included(base)
    base.has_one :activity_stream_event
    base.after_create :create_activity_stream_event
  end
  def create_activity_stream_event
    # something..
  end  
end
Vote.send(:include, VoteFuExtension)

添加一个名为 config/ refirminers/vote_fu.rb 的初始化器

require "vote_fu_extension"

<强 > 注

如果您想要在 Vote 模式中添加类方法, 请参考此 < a href="https://stackoverflow.com/ questions/2289884/rails-extending-extrecordbase/2293994#2329394" 回答 。

无耻的插头:我的"https://github.com/kandaboggu/vote_fu" rel=“nofollow noreferrer">fork vote_fu 宝石有一些新的特性和增强。

你可以尝试这样的东西:

class Vote
    after_create :create_activity_stream_event
    has_one :activity_stream_event

    def create_activity_stream_event
        # something..
    end
end

我想这比增加你的功能 和调用函数"后创造"和"有has_hone"。





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签