Reputation: 77778
Say I have a view helper:
def foo(s)
"hello #{s}"
end
A view might use the helper like this:
<div class="data"><%= foo(@user.name) %></div>
However, this <div>
will be updated with a repeating ajax call. I'm using a to_json
call in a controller returns data like so:
render :text => @item.to_json(:only => [...], :methods => [:foo])
This means, that I have to have foo
defined in my Item
model as well:
class Item
def foo
"hello #{name}"
end
end
It'd be nice if I could have a DRY method that could be shared in both my views and my models.
def say_hello(s)
"hello #{s}"
end
def foo
say_hello(name)
end
def foo
say_hello(label)
end
<div class="data"><%= item.foo %></div>
def observe
@items = item.find(...)
render :text => @items.to_json(:only=>[...], :methods=>[:foo])
end
I don't know the best way to handle this, but I don't want to completely go against best-practices here.
If you can think of a better way, I'm eager to learn!
Upvotes: 5
Views: 4627
Reputation: 5804
You could add some modules, and then have in the models that you want the method to work (on a specific attribute) something like this:
The 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 that would do it...
Upvotes: 5
Reputation: 37133
I would simply put this method in my model, which is available to both view and controller.
Model:
def say_hello
"hello #{self.name}"
end
To add this to all of 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 respond_to? handles the case where a model has no name column.
Upvotes: 1