Reputation: 141
Newbie to RoR. I can't grasp the concept of how to call a simple method on my form controller from my view. I want to collect 2 pieces of information form the view, call a method on the form controller that will retrieve a piece of information based on the parameters, and then display the piece of information on that same view or another one. Right now, I was trying to use a form controller instance variable to accomplish the displaying of the new piece of information--not sure how I will refresh the view to display it but that is a future hurdle. Right now, I can click my Submit button without getting any errors but it is clearly not hitting my form controller method. Here is my erb file for the view:
<h1>Enter Required Information</h1>
<%= form_tag (get_hotel_recommendation_path) do %>
<%= label_tag(:name, "Name:") %>
<%= text_field_tag(:name) %>
<%= label_tag(:date, "Date (yyyy-mm-dd):") %>
<%= text_field_tag(:date) %>
<%= submit_tag("Submit") %><br><br>
<%= label_tag(:recommendation, "Recommendation:") %>
<%= @recommended_hotel_name %>
<% end %>
Here is my form controller code:
class RecommendHotelController < ApplicationController
@recommended_hotel_name = ''
def collect_info
end
def get_hotel_recommendation
@recommended_hotel_name = Member.recommended_hotel_name( params[:name], params[:date] )
end
end
I really just want a simple and easy way to do this--not necessarily the best. I just need a quick UI to demonstrate my model code. And I need to get it done soon.
New form controller code:
class RecommendHotelController < ApplicationController
def collect_info
end
def get_hotel_recommendation
redirect_to recommend_hotel_path
end
protected
helper_method :recommended_hotel_name
def recommended_hotel_name
unless (params[:name].nil?)
Member.recommended_hotel_name(params[:name], params[:date])
end
end
end
Upvotes: 2
Views: 2198
Reputation: 211590
Once the controller hands over to the view, there's no going back to call additional methods. It is the controller's job to prepare everything the view might need in advance. Once inside the render
phase, there's no way to call controller methods.
The exception to this is helper methods which can be called. You need to declare any methods you want to use within your view explicitly. As an example:
helper_method :get_hotel_recommendation
def get_hotel_recommendation
# ...
end
Helper methods can also be located inside the associated helper module, and it's a good idea to put them there if they're used exclusively within views.
In your case, if you're using this only once, you should probably skip the assignment to an instance variable and just return the object in question. The view would look like:
<%= recommended_hotel_name %>
The adjusted controller method:
class RecommendHotelController < ApplicationController
protected
helper_method :recommended_hotel_name
def recommended_hotel_name
Member.recommended_hotel_name(params[:name], params[:date])
end
end
It's worth noting that declaring @recommended_hotel_name = ''
in the class context is probably not what you intend. This creates a class variable, not an instance variable. Instance variables in controllers must be defined inside the primary action method or inside a before_filter
method. Also remember that instance variables are nil
by default, so there's no need to initialize them to that first. An empty string and nil
are equivalent when used within a view, everything inside <%= ... %>
is converted to a string for you automatically.
Another thing to watch out for is leaving a space between a method name and its arguments. It should be form_tag(...)
and not form_tag (...)
. Normally this does not make a difference, Ruby can be very lenient, but sometimes it can subtly alter the way the arguments are interpreted leading to a lot of confusion as you try to diagnose the problem. Stylistically speaking, only keywords like if
, while
and case
have a space before the brackets as these are not method calls.
As to why your form isn't working, it's not clear. Those parameters should be submitted as you intend, but maybe you're not getting the right routing. Remember it's best to stick with the standard index
, new
, show
, and edit
names unless you're doing something exotic. In this case, you should probably define this as index
if it shows more than one record or show
if it's always one record.
Upvotes: 2
Reputation: 2361
You can get all the information from a form submit in the params
array. However, from your example, I would advise to use: form_for instead of using separate form_tags.
Upvotes: 0