How to implement multiple selection on Rails 3 - ruby-on-rails-3

I have an index where I'm showing a list of documents. I would like to implement a multiple select in order to do different actions to the documents the user has selected
I have created a
<%= check_box_tag 'id', 'document.id %>
for each document, inside a form_tag
But if I select multiple checkboxes, the params that are passed to the action are overwrited and I'm just receiving the id of the last checkbox I've selected in the id param.
¿Anyone knows how to implement multiple select?¿Any other approach?
I'm running Rails 3 and Ruby 1.8.7
Thanks in advance

You need to set :multiple => true
<%= check_box_tag 'id', document.id, :multitple => true %>
This will give you results in form of an array in params[:id]

Minor correction (plural):
<%= check_box_tag 'ids[]', document.id %>
ensure your model is properly set for attr_accessible something like :document_ids

Related

Using a 'new' form to make database changes

I have a user, who wants to be able to take vacation days off from work. My view looks like this:
<h2>Request Days Off</h2>
<%= form_for(#user, :as => :user, :url => vacation_days_path) do |f| %>
<div><%= f.label "How many vacation days would you like to take?" %>
<%= f.number_field :vacation_days %></div>
<div><%= f.submit "Submit" %></div>
<% end %>
In my controller, I have new and create methods. In all examples of the 'create' method I see on the internet, there is a line of code similar to
#person = User.new(user_params) or whatever
My issue is that I don't have a vacation_days model. Only a controller. I want to edit the User database, but creating a new user cannot be the answer (right?).
How do I create a working create method?
This is not really RESTful... However, if you want to update an existing user, you can do so like this
#user = User.find(params[:id])
#user.update_attributes(params[:user])
where params[:id] would hold the id of the user you want to update and params[:user] would hold the attributes you want to update.
Since you are using form_for(#user) with its form builder, it should be fine.
It doesn't seem to me that you need your separate controller for vacation days. Simply have a vacation_days/edit view, which contains your form, and have it submit to users/update.
For clarity, your action should be editing and updating your user, rather than 'creating' one. So, your controller action to update your user should have the line:
#user.update_attributes(params[:user])

belongs_to association and formtastic

I have a model Product which has a belongs_to association with another model Type. In the product's form, I'm using formtastic to display a select tag with all the types available in the database, like this:
<%= f.input :type %>
The select is showing up OK, but each option of it is an object instance of the Type model as a string, for example:
#<Type:0x00eff180c85c8>
Instead of that, I'd like to display the 'title' attribute of it, like:
Electronic
Domestic
...
Any ideas?
Try the member_label option, it sounds like what you want to do:
<%= f.input :type, :member_label => :title %>
The documentation has more examples.
Simply add this in your model
def name
return self.title
end

Editing multiple records at once - how to update without IDs

Still new to Rails. I'll try to provide as much detail as possible.
I have a form that lets me update multiple records at one time.
It's based off the 'Editing Multiple Individually' Railscast episode.
<%= form_tag(auction_clerk_path(#auction), :method => :put) do %>
<% #lots.each do |lot| %>
<%= fields_for "lots[]", lot do |f| %>
<%= f.number_field :sale_price %>
<% end %>
<% end %>
<% end %>
(Simplified to just include a single input for each instance)
An Auction contains multiple Lots (items for sale).
The auction_clerk_path is the route I'm using to just show all lots on one auction.
Everything is working just fine... until I use try to customize my lot paths...
I've added the following to my lot.rb file to be able to use:
/auctions/:auction_id/lots/:lot_number
instead of /auctions/:auction_id/lots/:id
def to_param
lot_number
end
So, in the form mentioned earlier, the fields render with name="lots[12][sale_price]" where 12 is the id.
However with the to_param change, now the fields render with name="lots[1][sale_price]" where 1 is the lot_number.
When I save, the submitted parameters are lot_numbers instead of ids.
So obviously when it tries to update, it won't find the correct records.
My method definition looks like this:
def save_clerking
#updated_lots = Lot.update(params[:lots].keys, params[:lots].values).reject { |l| l.errors.empty? }
if #updated_lots.empty?
flash[:notice] = "Lots updated"
redirect_to auction_clerk_path(#auction)
else
render :action => "clerk"
end
end
I either need to change my method definition to lookup by lot number, or change the form to somehow output IDs in the first place... but I don't know how.
Any help is appreciated. Thanks!
Fixed this through some help on another question.
I changed my method def to
#updated_lots = []
params[:lots].each do |lot_number, attributes|
lot = Lot.where("lot_number = ? AND auction_id = ?", lot_number, params[:auction_id]).first
if lot.update_attributes(attributes)
#updated_lots << lot
end
end
You could fetch the ids by lot number in the controller action and feed those to the update method instead of the params keys.

Rails syntax Passing POST parameters from a form to a controller

I'm new to Rails (and fairly new to programming in general) and I am building a web app for myself as a way to learn. Right now I am modifying scaffolded forms and such.
My question is with the "create" method in one of my controllers. There are two entities I am concerned with: the User table and the Habit table. I created a dropdown box in the _form partial for the Habit views to allow a person to select a user from a list of all available when creating a habit as below
<%= collection_select :user, :id, #users, :id, :first_name %>
The habit controller, of course, has
def new
#users = User.all
...
end
This works fine, and when the form submits it posts two hashes of parameters :habit and :user. Now, when I want to process the form input in the create method, I'm not sure how to use the syntax correctly and assign the user_id to the newly create habit. What I WANT to do is something like this
def create
#habit = Habit.new(params[:habit], params[:user])
end
This, of course, is improper syntax.
def create
#habit = Habit.new(params[:habit])
end
assigns the params from the :habit hash correctly, but then the user_id is left unset.
What works is the following, but the code is very lengthy, assigning each value manually.
def create
#habit = Habit.new(:user_id => params[:user][:id],
:description => params[:habit][:description],
:habit_method => params[:habit][:habit_method],
:time_reqd => params[:habit][:time_reqd],
:will_reqd => params[:habit][:will_reqd],
:active => params[:habit][:active])
end
So my question is, when dealing with a form that posts data in multiple hashes, what is the proper way to pass those parameters into some method in a controller?
So my question is, when dealing with a form that posts data in multiple hashes, what is the proper way to pass those parameters into some method in a controller?
Instead of saying Habit.new( <lots of stuff> ), just use Habit.new(params[:habit]). Rails will try to assign each key in the hash (in this case, the params[:habit] hash's keys) to a matching value on the object.
Thus, if params[:habit] has a :description key, it will be assigned to a field called description on your model. This is called mass assignment and is quite handy.
Now you can just do:
#habit = Habit.new(params[:habit])
#habit.user_id = params[:user][:id]
You may want to read the RoR Getting Started Guide, like this section, for more similarly handy features of Rails.
Change
<%= collection_select  :user, :id, #users, :id, :first_name %>
To
<%= collection_select  :habit, :user_id, #users, :id, :first_name %>
The existing scaffold code should just work after that
Alternate
<%= f.select :user_id, #users, :id, :first_name %>

Rails 3: client_side_validations gem and devise password validations

I've got the client_side_validations gem working really great on my forms. I'm using Devise for my users model and when I go to the edit_user_registration form, validations are thrown up for everything except the :current_password, :password, and :password_confirmation fields.
Fort instance is I leave the email blank, the validation pops up right when I tab out of the field. However, if I leave the current_password field blank and tab out of it nothing happen, then when I submit the form I get the error "1 error prohibited this user from being saved: password can't be blank"
Thanks for any help
http://pastie.org/1907464
Currently ClientSideValidations will filter out any conditional validators. Devise sets some of the validators as conditional: https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L24-32
The reason I did this is because there is no good way for the client to determine the true value of that conditional. I could do it at the time the form is generated but what if that conditional relied upon a value that could be changed on the form? So I opted to filter them and let things fall back to the server.
That was the idea but clearly it has imposed unfair limitations on some things. This being the most obvious (and popular).
So I plan on releasing a new version very soon that will allow you to explicitly override the conditional filters. It will work like this:
<%= f.text_field :password, :validate => { :presence => true, :confirmation => true } %>
or
<%= f.text_field :password, :validate => true %>
In the first case you can choose which validators to turn the filter off. In the 2nd case it will turn the filter off for all validators on that attribute. The conditional will be evaluated at the time the form is generated and if it passes it will add the validator to the input element for use on the client.
The master branch now supports this format. Point your Gemfile to it and you should be good
It’s simple! The gem extends the Rails default form builder, and all you have to do is set a :validate => true option on any form_for (or simple_form_for for simple form users) tag that you want the inline validations for. The form builder uses some rails reflections on your model validations to generate some json that gets included in a script tag after your form. The json is then used by the gem’s Javascript framework to perform the validations that need to be performed.
<%= form_for(#user, :url => registration_path(resource_name), :validate => true) do |f| %>