Helper methods for models in Rails
Asked Answered
G

2

15

Is there a proper place for helper methods for models in Rails? There are helper methods for controllers and views, but I'm not sure where the best place to put model helper methods. Aside from adding a method to ActiveRecord::Base, which I'd prefer not to.

UPDATE: It seems Concerns make a lot of sense. Here's an example of what I want. Certain models can never be deleted, so I add a callback that always throws an exception:

before_destroy :nope
def nope
  raise 'Deleting not allowed'
end

With concerns, I could do something like this?

class MyModel < ActiveRecord::Base
  include Undeletable
end

module Undeletable
    extend ActiveSupport::Concern

    included do 
      before_destroy :nope 
    end

    def nope
      raise 'Deleting not allowed'
    end
end

Is this the Rails way of doing this?

Ghee answered 19/3, 2015 at 9:36 Comment(5)
Why don't you use plain old Ruby module and mix it into all the classes you want?Diacaustic
What does 'helper for model' mean? Maybe you are looking for decorator?Bryon
It would help if you gave an example i think, then people could advise on convention: there's lots of ways to do anything, but generally sticking to convention is a good idea.Strengthen
Can you please add an example (code) what kind of methods you want to add to ActiveRecord::Base.Willumsen
A plain old Ruby module makes sense and that's what I was going to do, just figured there was a more Rails way to do this. Which I think there is with Concerns. I've added an example.Ghee
P
19

If you want to use a helper_method my_helper_method inside a model, you can write

ApplicationController.helpers.my_helper_method

If you need a bit more flexibility, for example if you also need to override some methods, you can do this:

class HelperProxy < ActionView::Base
  include ApplicationController.master_helper_module

  def current_user
    #let helpers act like we're a guest
    nil
  end       

  def self.instance
    @instance ||= new
  end
end

and then use with

HelperProxy.instance.my_helper_method

If you have strong nerves, you can also try to include the ApplicationController.master_helper_module directly into your model.

via : makandracards's post.

For your reference: http://railscasts.com/episodes/132-helpers-outside-views

Placida answered 19/3, 2015 at 9:47 Comment(4)
I was looking for the same and I found your answer helpful in my case. Thanks :)Sitter
@HetalKhunti : Glad to hear you found it helpfulPlacida
I think when used sparingly, ApplicationController.helpers.my_helper_method can be really helpful to share code between models without creating and including a module specifically for it.Claudicant
Can you provide the link to makandracards?Classy
C
15

If what you are asking is where to put code that is shared across multiple models in rails 4.2, then the standard answer has to be to use Concerns: How to use concerns in Rails 4

However, there are some good arguments (e.g. this) to just using standard rails module includes, and extends as marek-lipka suggests.

I would strongly recommend NOT using ApplicationController helper methods in a model, as you'll be importing a lot unnecessary baggage along with it. Doing so is usually a bad smell in my opinion, as it means you are not separating the MVC elements, and there is too much interdependency in your app.

If you need to modify a model object by adding a method that is just used within a view, then have a look at decorators. For example https://github.com/drapergem/draper

Chatterjee answered 19/3, 2015 at 10:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.