Reputation: 3784
So my problem is showing something that a model has in a nice and simpler way.
So what currently works?
In my viewer this works fine:
<%= text_field_tag(:first_name, (current_user.present? ? current_user : '').first_name.present? ? current_user.first_name : '') %>
However this is too long and really hard to maintain, especially when I have several more fields.
So to avoid that I made this in my controller
def user_vals(value)
if(current_user.present?)
current_user.value.present? ? current_user.value : ''
end
return ''
end
Within this controller I can call user_vals(:first_name)
but get undefined method
value'` error. Furthermore I cannot just call
<%= text_field_tag(:first_name, @user_vals(:first_name)) %>
As I am getting some syntax error with brackets but that's not the real issue.
So my ultimate goal is to have something like this:
<%= text_field_tag(:first_name, @user_vals(:first_name)) %>
Rather than the first code I've given above. How can I achieve that?
Upvotes: 0
Views: 143
Reputation: 18037
I would recommend to take a step back and try to use Duck Typing to solve this...
What you have right now is a current_user
method. This method can return whatever object it wants if the user is not logged in, and that object can respond to whatever it wants. Here's a simplified example:
def current_user
@user || OpenStruct.new(first_name: "")
end
Note: I'm assuming @user
holds the currently-signed in user... but this may be a call to super
instead, or whatever else depending on your implementation.
So now, instead of branching based on what type of object is coming back from the current_user
method, you can now just use the returned object without regard.
current_user.first_name # => Either the User object's first name or `""`
You can go further with this by creating e.g. a GuestUser class and having GuestUser.new
returned instead of the OpenStruct
above. Guestuser would be a model that is not data-base backed and could respond to any number of methods as needed.
This idea has been represented by many others as well. And using a class to prevent repeated code switching based on nil actually has a name: The Special Case Pattern. As a quick, free example, see the Guest User RailsCast. Or, if you subscribe to Ruby Tapas, be sure to check out episode 112: Special Case. This topic, and many others, are also covered in depth in Avdi Grimm's excellent book: Confident Ruby, which I highly recommend.
Upvotes: 0
Reputation: 106782
You can use try
in this case. Just write:
<%= text_field_tag(:first_name, current_user.try(:first_name)) %>
See: http://apidock.com/rails/Object/try
Upvotes: 1