Rails: create a method available in all views and all models

I would like to define a method available in both my views and my models

Let's say I have a view helper:

def foo(s) "hello #{s}" end 

The view may use an assistant:

 <div class="data"><%= foo(@user.name) %></div> 

However, this <div> will be updated by calling ajax again. I use the to_json call in the controller, which returns the data as follows:

 render :text => @item.to_json(:only => [...], :methods => [:foo]) 

This means that I must have foo defined in my Item model:

 class Item def foo "hello #{name}" end end 

It would be nice if I had a DRY method that could be used both in my representations and in my models.

Usage may look like this:

Assistant

 def say_hello(s) "hello #{s}" end 

User.rb Model

 def foo say_hello(name) end 

Model Item.rb

 def foo say_hello(label) end 

View

 <div class="data"><%= item.foo %></div> 

controller

 def observe @items = item.find(...) render :text => @items.to_json(:only=>[...], :methods=>[:foo]) end 

I don’t know how best to deal with this, but I don’t want to go completely against the best practices here.

If you can come up with a better way, I really want to find out!

+4
source share
2 answers

You can add some modules, and then in models that you want the method to work (by a specific attribute) like this:

Modules (add this to the lib folder)

 module hasFoo def self.included(base) base.extend ClassMethods end end module ClassMethods def has_foo(method) define_method foo do field = self.send(method.to_sym) field end end end 

Then in your model just add

 has_foo :name 

Then you can just call model.foo

And I think I will do it ...

+5
source

I would just put this method in my model, which is available both for viewing and for the controller.

Model:

 def say_hello "hello #{self.name}" end 

To add this to all your models:

 class AbstractModel < ActiveRecord::Base self.abstract_class = true def say_hello self.respond_to?(:name) ? "hello #{self.name}" : "hello" end end class MyModel < AbstractModel end 

The ternary operator on response_to? handles the case when the model does not have a column of names.

+1
source

Source: https://habr.com/ru/post/1304425/


All Articles