开发者

Rails extending models without modifying the base file

开发者 https://www.devze.com 2023-02-25 10:32 出处:网络
I\'ve got two Rails 2.3 applications, we\'ll call them admin and frontend. In admin I have all my models specified in app/models. In frontend I have those models s开发者_开发知识库ymlinked. I would li

I've got two Rails 2.3 applications, we'll call them admin and frontend. In admin I have all my models specified in app/models. In frontend I have those models s开发者_开发知识库ymlinked. I would like to add frontend specific methods to a model that only show up for the frontend application, and not the admin app.

At first I tried just adding config.autoload_paths += "#{RAILS_ROOT}/app/augments/address.rb" with:

class Address
  def hello
    "hello world"
  end
end

But that just wasn't loaded. Calls to Address.first.hello would be met with undefined method 'hello'.

If I require a file that does this:

Address.class_eval do
  def hello
    "hello world"
  end
end

It is loaded once, and for the first hit in development it works, but all subsequent reloads it fails. This is due to config.cache_classes = false in development.

A semi-working solution is to run that from ApplicationController:

class ApplicationController < ActionController::Base
  Address.class_eval do
    def hello
      "hello world"
    end
  end
end

Which does reload and works every time in dev andprod, but doesn't work for script/runner or script/console. (If this is the only solution I'm sure we could extract that out into a module and include ModelExtensions in ApplicationController.)

Is there something I can add to environment.rb or an initializer that will get reloaded every time in development?


To extend your class you should use module and include it in your model. Something like this:

module  Address
  def hello
    "hello world"
  end
end

This is an old but always interesing article on that argument: http://weblog.jamisbuck.org/2007/1/17/concerns-in-activerecord

To include the module only in frontend you should check if the module exists with:

Class A
  include Address if defined? Address
end
0

精彩评论

暂无评论...
验证码 换一张
取 消