I have a couple of methods I'd like to share between models rather than copy开发者_开发百科ing and pasting them. In a controller, I can do this by putting the methods in application_controller.rb which automatically gets included in every controller. Is there a similar thing for models?
Thanks!
You can create a file called functionality.rb or something similar in the lib directory of your Rails app. Make the file named after the module to autoload it when Rails starts. For example, if I wanted to add flagging to multiple models, I'd create a file called lib/flagging.rb, and it would look like this:
module Flagging
  # Flags an object for further review
  def flag!
    self.update_attribute(:flagged, true)
  end
  # Clears all flags on an object
  def deflag!
    self.update_attribute(:flagged, false)
  end
end
In every model I wanted to add this functionality to, I'd do the following:
class Foo < ActiveRecord::Base
  include Flagging
end
I'd then be able to do something like:
foo = Foo.create
foo.flag!
The top solution above worked for me. In Rails 3 I found I also had to update the application.rb file with: config.autoload_paths += Dir["#{config.root}/lib/**/"] as answered here: Best way to load module/class from lib folder in Rails 3?
You can either a) do something to similar to application_controller and create a model class from which others can subclass or b) use a module.
There are a number of ways you can share methods between 2 model classes.
- Use inheritance if the models are related to each other, e.g. a shared parent class that contains the methods, or one subclasses the other that contains the methods.
- Use modules/mixins that can be shared among multiple models
To add to the answer by Josh, sometimes you might want to share some code defining a polymorphic association. You can't just put the has_many method call in your module, because  you will get an error, for example in a module called Votable:
undefined method `has_many' for Voteable:Module (NoMethodError)
So instead, you need to use the self.included(base) method and base.instance_eval. Here's an example with my Voteable module:
module Voteable
  def self.included(base)
    base.instance_eval do
      has_many :votes, as: :voteable
      has_many :voters, through: :votes
    end
  end
  def voted_up_by?(user)
    user and votes.exists?(value: 1, voter_id: user)
  end
  def voted_down_by?(user)
    user and votes.exists?(value: -1, voter_id: user)
  end
end
Now you can include Voteable in models that will have that behavior. This will execute the self.included(base) method and it will define the association on the including class.
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论