Reputation: 1176
I have a kind of social network website.
I have a logic to create the path for the user, and select an avatar for each user described in UsersHelper methods user_path(user) and user_avatar(user).
Instead I want to have methods like user.path and user.avatar, but I don't want to have that code inside the model file.
I tried extending the User class inside the helper:
module UsersHelper
class User
def avatar
...
end
end
end
That doesn't work - the method I added aren't recognized (I'm guessing Rails dynamically generates the ActiveRecord class on demand so my methods don't apply?)
I'd really appreciate ideas
Upvotes: 0
Views: 1526
Reputation: 14851
Draper is an awesome little gem that does an excellent job of achieving the functionality you're looking for (adding view / presentation specific code while still making it "feel" like the model you're working with). We've removed almost all of our model-specific helpers after starting to use draper.
Basically, it works by defining decorators, which work like a wrapper around your model. A decorator looks and feels like the model it's decorating, but can have additional functionality defined on top of it. In addition, you can restrict access to certain fields and lock stuff down if you like.
For your example, adding a decorator would be as simple as:
(in app/decorators/user_decorator.rb)
class UserDecorator < ApplicationDecorator
decorates :user
def avatar
# your implementation
end
(in your controller)
def index
respond_with UserDecorator.decorate(User.all)
end
(in your views)
<div class='avatar'><%= user.avatar %></div>
<div class='name'><%= user.name %></div>
Upvotes: 1
Reputation: 10106
First, there's a reason helpers are separated from models. According to the MVC pattern your model shouldn't know anything about your helpers, and not vice versa either (the latter is usually ignored in Rails, though).
But, if you want to do this, you need to do class ::User
in model UsersHelper
, or the following:
module UsersHelper
end
class User
end
The reason for this is that Ruby namespaces classes. So you defined UsersHelper::User
, while your model is called User
. Calling the class ::User
or defining it outside the module forces it into the root namespace.
However, as I said, this is not the "correct" way to do it. A better way would be how you're already doing it, or maybe using a decorator pattern.
Upvotes: 1
Reputation: 8103
Helpers are intended to use with the views, not with the models.
If you wish to have something like user.avatar
, you have to add it to your model.
If you want to stick it in the helpers, then in the UsersHelper
add a user_avatar
method.
Upvotes: 0