开发者

How/When/Where to Extend Gem Classes (via class_eval and Modules) in Rails 3?

开发者 https://www.devze.com 2022-12-31 01:49 出处:网络
What is the recommended way to extend class behavior, via class_eval and modules (not by inheritance) if I want to extend a class buried in a Gem from a Rails 3 app?

What is the recommended way to extend class behavior, via class_eval and modules (not by inheritance) if I want to extend a class buried in a Gem from a Rails 3 app?

An example is this:

I want to add the ability to create permalinks for tags and categories (through the ActsAsTaggableOn and ActsAsCategory gems).

They have defined Tag and Category models.

I want to basically do this:

Category.class_eval do
  has_friendly_id :title
end

Tag.class_eval do
  has_friendly_id :title
end

Even if there are other ways of adding this functionality that might be specific to the gem, what is the recommended way to add behavior to classes in a Rails 3 application like this?

I have a few other gems I've created that I want to do this to, such as a Configuration model and an Asset model. I would like to be ab开发者_如何转开发le to add create an app/models/configuration.rb model class to my app, and it would act as if I just did class_eval.

Anyways, how is this supposed to work? I can't find anything that covers this from any of the current Rails 3 blogs/docs/gists.


I do this as follows, first add a file to config/initializers where you can require the files that contain your extensions:

# config/initializers/extensions.rb
require "#{Rails.root}/app/models/category.rb"
require "#{Rails.root}/app/models/tag.rb"

Then you can just re-open the classes and add whatever else you need:

# app/models/category.rb
class Category
  has_friendly_id :title
end

Only downside is that the server has to be restarted for any changes to these files to take effect, not sure if there is a better way that would overcome that.


You can use rails_engine_decorator gem: https://github.com/atd/rails_engine_decorators

Just add in your Gemfile:

gem 'rails_engine_decorator'

And user class_eval in your decorators:

/app/decorators/models/category_decorator.rb
/app/decorators/models/tag_decorator.rb

It works for me. I hope you find it useful!

0

精彩评论

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