I have an edit page with the following code, basically a dropdown and button that calls update.
<% form_tag('switch_car', :method => :put) do%>
<div class="field">
<label>Car Name:</label>
<%= select("params", ":id", #available_cars.collect {|v| [v.name, v.id]})%>
</div>
<div>
<%= submit_tag "Switch Car" %>
</div>
<% end %>
The server reads like the params is being set:
Parameters: {"utf8"=>"Γ£ô", "authenticity_token"=>"8vHXrnICaOKrGns6FfMUcd/dWo5kpNKpA8F5l5ozRkY=", "params"=>{":id"=>"9"}, "commit"=>"Switch Car"}
However, when I put the params into a session I get nothing. It seems to be always nil. Not sure what I am doing wrong? Here is code in the controller.
def update
if params[:id]
session[:car_info_id] = params[:id]
redirect_to entry_url
else
redirect_to switch_car_path
end
end
It always gets redirected to the switch_car_path so I am assuming params[:id] is always nil. When I put if params[:id] == nil it goes to the entry_url.
Thanks in advance.
you want params[:params][":id"]
Alternatively, you could put this in your view:<%= select("car_info", "id", #available_cars.collect {|v| [v.name, v.id]})%>
And then in your controller:if params[:car_info][:id]
While the other answer would work, this is probably what you'd want to be doing (using select_tag(:id) will automatically add an :id key/value to the params hash):
<% form_tag('switch_car', :method => :put) do %>
<div class="field">
<label>Car Name:</label>
<%= select_tag(:id, options_from_collection_for_select(#available_cars, "id", "name")) %>
</div>
<div>
<%= submit_tag "Switch Car" %>
</div>
<% end %>
Then you can easily access params[:id] in the controller.
Related
I can't find how to display a dynamic label in Rails, i've tried using the :value => show_name property but it didn't work, it only displays Show name. Here is the view code
<p>
<div class="control-group">
<%= f.label :show_name, :value => :show_name, :class => 'control-label' %>
<%= #this next line fails with undefined method `show_name' for #<ActionView::Helpers::FormBuiler>
#f.label f.send :show_name, :class => 'control-label'
%>
<div class="controls">
<%= f.text_field :variable_value, :class => 'text_field' %>
<%= f.hidden_field :variable_id, :class => 'text_field' %>
<%= f.hidden_field :show_name, :class => 'text_field' %>
</div>
</div>
<p>
and if needed here is the show_name definition inside my model.
def show_name
Variable.find_by_id(self.variable_id).name
end
Ok, so i end up finding a solution that is very DRY, thank to this post. And the only thing im going to do is explain a lit bit more what to do:
First we are going to asume the most complex case in which we have nested forms and so we are using fields_for inside a form_for method:
<!-- f represents the form from `form_for` -->
<%= f.fields_for :nested_model do |builder| %>
<p>
<div class="control-group">
<!-- here we are just calling a helper method to get things DRY -->
<%= builder.label return_value_of_symbol(builder,:show_name), :class => 'control-label' %>
<div class="controls">
<%= builder.text_field :variable_value, :class => 'text_field' %>
<%= builder.hidden_field :variable_id, :class => 'text_field' %>
</div>
</div>
</p>
<% end %>
Note that we included the builder object(as specified in the fields_for call) in the parameters of our helper.
In our helper we define the return_value_of_symbol function
def return_value_of_symbol(obj,sym)
# And here is the magic, we need to call the object method of fields_for
# to obtain the reference of the object we are building for, then call the
# send function so we send a message with the actual value of the symbol
# and so we return that message to our view.
obj.object.send(sym)
end
Use label_tag, put the show_name on a instance variable on your controller and use like this:
<%= label_tag #show_name, nil, :class => 'control-label' %>
EDIT:
On your application_helper.rb, create a helper method similar to this one:
def show_name(name)
content_tag(:label, name, :class => 'control-label')
end
Then you can use the show_name(name) on your views like this:
<%= show_name(#name) %>
Just remember to populate the #name variable.
I have _form.html.erb
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :password %>
<%= f.password_field :password %>
Now if I render this form in homepage, HTML code should be:
<label for="session_name">Name</label>
<input id="session_name" name="session[name]" size="30" type="text">
...
If I change my _form.html.erb to:
<%= f.label :name %>
<%= f.text_field :name, disabled: true %>
...
HTML code should be:
...
<input disabled="disabled" id="session_name" name="session[name]" size="30" type="text">
...
But, I don't want to change my _form.html.erb, so how can I pass the disabled: true into my form? I tried to use render partial: but don't know syntax.
I just learn Ruby on Rails for 2 weeks, so please help me.
i donno why u wnt to do so but u can solve the prob by this method. Try doing-
in application helper, add method -
def add_disabled
#i suppose that u want the field to be disabled in the users controller for edit action but not for other controllers or actions
return "disabled='disabled'" if params[:controller] == "users" and params[:action] == "edit"
end
in _form.html.haml
= f.text_field :name, #{add_disabled}
this will call the helper method and return "disabled='disabled'" depending upon the controller and action
I am confused by the addition of [:session] to params. It also seems to break my website. Can someone please explain what this does for me?
class SessionsController < ApplicationController
.
.
.
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_back_or user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
.
.
.
end
Error message:
1) Authentication signin with invalid information
Failure/Error: before { click_button "Sign in" }
NoMethodError:
undefined method []' for nil:NilClass
# ./app/controllers/sessions_controller.rb:7:increate'
# (eval):2:in click_button'
# ./spec/requests/authentication_pages_spec.rb:18:inblock (4 levels) in '
EDIT 8/2
I believe the problem is related to a switch from form_for to form_tag. I lost the reference to sessions in the switch because I could not figure out how to properly include it. If anyone has any advice on this issue it would be most appreciated. I am wondering if there is a practical reason for wanting it to be params[:session][:email] instead or is it just for organization?
new.html.erb
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_tag sessions_path do %>
<%= label_tag :email %>
<%= text_field_tag :email %>
<%= label_tag :password %>
<%= password_field_tag :password %>
<%= submit_tag "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
Try removing the [:session] brackets, that worked for me
It brakes your code 'cos the params[:session] is nil I think and you trying to get [:email] from nil, what ofcourse should cause the exception. There should be some code in tutorial that defines params[:session] hash. Try to look better.
To make your code stable you have to be sure that params[:session] is always defined or try to use ternar function params[:session] ? params[:session][:email] : ''
You can replace this in your view :
<%= form_for :session, :url => sessions_path do %>
<%= label_tag :email %>
<%= text_field_tag :email %>
<%= label_tag :password %>
<%= password_field_tag :password %>
<%= submit_tag "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
form_tag generate just an HTML form tag and form_for is used to describe something. All the inputs for a field of a form create with form_for will have a name like this : user_session[email]. So, when you submit the form, in your controller, you will have this : params[:user_session][:email].
When the view pass the parameters to controller,
controller gets nil for all of the arguements somehow.
Can anyone how to fix this?? Thanks!
and I have no model called "Message"
controllers/messages_controller.rb
def deliver
recipient = User.find_by_username(params[:recipient])
subject = params[:subject]
body = params[:body]
current_user.send_message(recipient, body, subject)
redirect_to :controller => 'messages', :action => 'received'
flash[:notice] = "message sent!"
end
views/messages/new.html.erb
<%=form_for :messages, url: url_for( :controller => :messages, :action => :deliver ) do |f| %>
<div class="field">
<%= f.label :subject %><br />
<%= f.text_field :subject %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
<% end %>
Check your source HTML to better understand what FormHelpers do.
With the form_for f.text_field will generate names attributes in the format:
messages[subject]
Consequently, your params will be in the format:
params[:messages][:subject]
You can also use <%= debug params %> to inspect what's in params, it's very helpful.
You can get parameter value using datas = params[:messages]
These values are in array form. So you can fetch array datas If you want to individual data then usesubject = datas[:subject]
body = datas[:body]
To check run following code in view
<%= subject %>
this gives the value of subject.
Anyone else working through Chapter 11 Exercises for Michael Hartl's Rails Tutorial 2nd Edition?
Chapter 11, Exercise 3 asks:
Refactor Listing 11.31 by adding partials for the code common to the following/followers pages, the Home page, and the user show page.
I'm not seeing anything worth refactoring in the homepage, user show page, or the show_follow page
If anyone came up with something worthwhile for this exercise, would love to know.
Thanks!
You can refactor the first block of code from Listing 11.31:
<section>
<%= gravatar_for #user %>
<h1><%= #user.name %></h1>
<span><%= link_to "view my profile", #user %></span>
<span><b>Microposts:</b> <%= #user.microposts.count %></span>
</section>
because it is essentially the same as the views\shared_user_info.html.erb partial used on the home page (Listing 10.32). Therefore, you can replace the block of code above with this:
<%= render 'shared/user_info' %>
Note that you will also need to add <% #user ||= current_user %> to the top of the views\shared_user_info.html.erb partial (which is the same as what was necessary to add to the stats partial in Listing 11.20).
Additionally, there is some duplication (though not exact duplication) between the feed_item + feed partials with the user + micropost partials, where depending on which page is being displayed (follow_show, home, or profile) there are one or more elements being listed (name, gravatar, admin delete link, micropost content, micropost time stamp, and micropost delete link). Those could probably be refactored too to eliminate the feed_item+feed partials and replace them with a combination of the user + micropost partials depending on the page.
I just worked through this exercise and found a solution that works.
First I changed around app/views/shared/_user_info.html.erb to use the #user variable if it is set, and the current_user variable otherwise.
app/views/shared/_user_info.html.erb:
<% if #user %>
<%= link_to gravatar_for(#user, size: 52), #user %>
<h1>
<%= #user.name %>
</h1>
<span>
<%= link_to "view my profile", #user %>
</span>
<span>
<%= pluralize(#user.microposts.count, "micropost") %>
</span>
<% else %>
<%= link_to gravatar_for(current_user, size: 52), current_user %>
<h1>
<%= current_user.name %>
</h1>
<span>
<%= link_to "view my profile", current_user %>
</span>
<span>
<%= pluralize(current_user.microposts.count, "micropost") %>
</span>
<% end %>
Then I replaced the corresponding information in app/views/users/show_follow.hmtl.erb with the partial _user_info.html.erb
app/views/users/show_follow.hmtl.erb:
<div class="row">
<aside class="span4">
<section>
<%= render 'shared/user_info' %>
</section>
<section>
<%= render 'shared/stats' %>
<% if #users.any? %>
<div class="user_avatars">
<% #users.each do |user| %>
<%= link_to gravatar_for(user, size: 30), user %>
<% end %>
</div>
<% end %>
</section>
</aside>
<div class="span8">
<h3><%= #title %></h3>
<% if #users.any? %>
<ul class="users">
<%= render #users %>
</ul>
<%= will_paginate %>
<% end %>
</div>
</div>
I hope this answer helps anyone going through M. Hartl's tutorial.