Categories

See More
Popular Forum

MBA (4887) B.Tech (1769) Engineering (1486) Class 12 (1030) Study Abroad (1004) Computer Science and Engineering (988) Business Management Studies (865) BBA (846) Diploma (746) CAT (651) B.Com (648) B.Sc (643) JEE Mains (618) Mechanical Engineering (574) Exam (525) India (462) Career (452) All Time Q&A (439) Mass Communication (427) BCA (417) Science (384) Computers & IT (Non-Engg) (383) Medicine & Health Sciences (381) Hotel Management (373) Civil Engineering (353) MCA (349) Tuteehub Top Questions (348) Distance (340) Colleges in India (334)
See More

How to make custom Helpers in Rails 3?

Course Queries Syllabus Queries

Max. 2000 characters
Replies

usr_profile.png

User

( 4 months ago )

 

I'm fairly new to Rails, and I was confused as to how I could pass local variables outside the if...else statement. It looks like creating a method in the helper file is the conventional way to do this, but I wasn't sure how to do this.

So I'm trying to get the Author of a Mission. If the author of a mission doesn't exist, I want to use the author of its parent Syllabus (missions belong to syllabus). And then I want to print out the username of that author. I was able to do this when I was dealing with only one mission, like:

//controller
@mission = Mission.first
if !@mission.author.blank?
  @author = @mission.author
else
  @author = @mission.syllabus.author
end

//view
<%= @author.username %> 

but I wasn't sure how to do this when I was dealing with a foreach loop:

//controller
@mission = Mission.all

//view 
<% @mission.each do |mission| %>
..(where do I put the logic of finding author? I can't put it in my controller anymore and it won't pass the @author variable outside the if else statement if I put the logic here in the view)..
<%= @author.username %>
<% end %>

My futile attempt was to create a helper:

def author_getter(mission_id)
  @mission = Mission.find(params[:mission_id])
  if !@mission.author.blank? 
    @author = @mission.author 
    return @author
  else
    @author = @mission.syllabus.author  
    return @author
  end 
end

and putting the below inside the loop

<%= author_getter(mission) %>

However, this didn't work. What would be the best way to pass on a variable outside the if...else statement?

usr_profile.png

User

( 4 months ago )

Your helper method is a little confused. Helpers shouldn't be poking around in params, they should just be doing things with the arguments they're called with. You're passing in a mission_id but not using it, you're also calling it with (apparently) a mission object when the parameter name indicates than an ID is being asked for. Also, you don't need to be messing around with instance variables in helpers, just plain old variables will do.

Adjust the interface to ask for a Mission object and then use that object:

def author_of(mission)
  mission.author.present?? mission.author : mission.syllabus.author
end

Or, since mission.author should be nil or there, you can take advantage of the falseness of nil:

def author_of(mission)
  mission.author || mission.syllabus.author
end

Then in your ERB:

<!-- Note that you should use the plural @missions for a collection, you'll have to fix your controller as well. -->
<% @missions.each do |mission| %>
    <%= author_of(mission).username %>
<% end %>

Of course, once we've simplified and corrected your helper, you might decide that it is too small to be worth bothering with; if so, then you could ditch the helper and do it all in ERB:

<% @mission.each do |mission| %>
    <%= (mission.author || mission.syllabus.author).username %>
<% end %>

However, I think you have this logic in the wrong place: this should be inside Mission itself so that everything (other models, JSON builders, ...) can take advantage of it. So, a method like this would make sense:

class Mission
  def real_author
    author || syllabus.author
  end
end

then you can say this in your ERB:

<% @missions.each do |mission| %>
    <%= mission.real_author.username %>
<% end %>

what's your interest


forum_ban8_5d8c5fd7cf6f7.gif