rails radio button for all users approval in one shot - ruby-on-rails

I'm trying to use radio buttons to make administrators approve users. So in the page I have a list for all the users waiting for approval (a true/false value in user model). After the administrator has set "yes" or has left "no" on the radio button field of all of them, he should press the unique submit button.
I'm trying to figure out how to pass to the controller all of the users for the approval update.`
<%= form_tag(approve_url, :html => { class: "form-inline"} )do |f| %>
<table>
<% #tobeapproved.each do |user| %>
<tr >
<td>
<%= user.name %>
</td>
<td>
<%= user.surname %>
</td>
<td>
<%= user.email %>
</td>
<td>
<%= label :approved %>
<%= radio_button_tag "approved[#{user.id}]", "true" %> Approved
<%= radio_button_tag "approved[#{user.id}]", "false" %> Not approved
</td>
</tr>
<% end %>
</table>
<%= f.submit %>
<% end %>
On submit I should get "approved[id]"=>{"true/false"} right? I'm very new on all of this.
Thank you

In the end I figured out how to do such a thing.
<%= form_tag(approve_url, :html => { class: "form-inline"}) do |f| %>
<table>
<% #tobeapproved.each do |user| %>
<tr >
<td>
<%= user.name %>
</td>
<td>
<%= user.surname %>
</td>
<td>
<%= user.email %>
</td>
<td>
<%= radio_button_tag "approved[#{user.id}]", "true" %> Approved
<%= radio_button_tag "approved[#{user.id}]", "false", true %> Not approved
</td>
</tr>
<% end %>
</table>
<%= submit_tag 'Confirm'%>
It gets to me something like this in params:
"approved"=>{"27"=>"false", "26"=>"false", "25"=>"true"}
And in my controller:
def update
#users = params[:approved]
logger.debug "The object is #{#users}"
respond_to do |format|
#users.each_pair do |key, value|
user = User.find(key)
user.update_attribute(:approved, value)
end
format.html { redirect_to :action => :list, notice: 'Users updated' }
end
But I imagine this code kind of sucks. Anybody knows how to better it?

Related

Form_tag routing error after unsuccessful submit

I have an index page with a partial form to submit new records to Package model. I keep this form in the index page, so the user doesn't need to leave the page when repeating this action, several times.
In the same page I have a form_tag fir multiple updates for the same controller, namely packages_controller.
Everything works fine, except the following: when hit the update button, going to the form BUT instead of submitting I go back (with the browser) and try to select other records to be updated then I have a routing error:
Routing Error
No route matches [PUT] "/projects/47/orderlines/18/packages"
My index page looks like this:
<% if current_user %>
<%= render "packages/form" %>
<% end %>
<% if #packages.count >= 1 %>
<table class="table table-striped">
<thead>
<tr>
<th> <input type="checkbox" id="selectAll" value="selectAll"></th>
<th>Packed </th>
<th>#No.</th>
<th>Type</th>
<th>Gross weight</th>
<th>Length</th>
<th>Width</th>
<th>Height</th>
<th></th>
<th>Container</th>
</tr>
</thead>
<%= form_tag edit_multiple_project_orderline_packages_path, method: :get do %>
<tbody>
<% for package in #packages %>
<% if package.packed== true %>
<% #label_type="success" %>
<% else %>
<% #label_type="default" %>
<% end %>
<tr>
<td><%= check_box_tag "package_ids[]", package.id %></td>
<td><span class="label label-<%= #label_type %>"><% if package.packed==true %>Packed<% else %>Unpacked<% end %></span></td>
<td><%= package.package_no %></td>
<td><%= package.package_type %></td>
<td><%= package.gross_weight %></td>
<td><%= package.length %></td>
<td><%= package.width %></td>
<td><%= package.height %></td>
<% if #orderline.packages.count >= 1 %>
<td><%= link_to 'Delete', [package.orderline.project, package.orderline, package],
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<td><%= #containers.find(package.container_id).container_id if package.packed %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<%= submit_tag "Add to container", class: "btn btn-primary" %>
<% end %>
<br />
<%= will_paginate %>
<br>
And the multiple_edit form
<div class="col-sm-4">
<%= form_tag update_multiple_project_orderline_packages_path, method: :put do %>
<ul>
<% #packages.each do |package| %>
<li>
<%= hidden_field_tag "package_ids[]", package.id %>
<%= package.package_no %>
<%= package.container_id %>
<% package.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</li>
<% end %>
</ul>
<%= fields_for :package do |f| %>
<div class="field">
<%= f.label :package_no %><br />
<%= f.text_field :package_no, :class => "form-control" %>
</div>
<br />
<div class="field">
<%= f.label :container_id %><br />
<%= select_tag 'package[container_id]', options_from_collection_for_select(#project.containers, 'id', 'container_id', default_blank: true), prompt: "- Select container -", :class => "form-control" %>
</div>
<br />
<div class="field">
<%= f.label :packed %><br />
<%= f.select :packed, [["Packed", true], ["Unpacked", false]],{ prompt: "- Packing -"},{ :class => "form-control" } %>
</div>
<% end %>
<div class="actions">
<br />
<%= submit_tag "Update", :class => "btn btn-primary" %>
</div>
<% end %>
</div>
And the packages controller edit_multiple actions:
def edit_multiple
#project = Project.find(params[:project_id])
#packages = Package.find(params[:package_ids])
end
def update_multiple
#packages = Package.find(params[:package_ids])
#packages.reject! do |package|
package.update_attributes(package_params.reject { |k,v| v.blank? })
end
if #packages.empty?
redirect_to project_orderline_packages_url
else
#package = Package.new(package_params)
render "edit_multiple"
end
end
packages_controller create action:
def create
project = Project.find(params[:project_id])
orderline = project.orderlines.find(params[:orderline_id])
#package = orderline.packages.new(package_params)
#package.save
if #package.save
flash[:success] = "Package(s) was successfully added."
redirect_to :back
else
render 'new'
end
And my routes:
resources :projects do
resources :containers
resources :orderlines do
resources :packages do
collection do
put :packed
get :edit_multiple
put :update_multiple
end
end
end
end
I just added my routes here:
edit_multiple_project_orderline_packages_path GET /projects/:project_id/orderlines/:orderline_id/packages/edit_multiple(.:format)
packages#edit_multiple
update_multiple_project_orderline_packages_path PUT /projects/:project_id/orderlines/:orderline_id/packages/update_multiple(.:format)
packages#update_multiple
project_orderline_packages_path GET /projects/:project_id/orderlines/:orderline_id/packages(.:format)
packages#index
POST /projects/:project_id/orderlines/:orderline_id/packages(.:format)
packages#create
new_project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/new(.:format)
packages#new
edit_project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/:id/edit(.:format)
packages#edit
project_orderline_package_path GET /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#show
PATCH /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#update
PUT /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
packages#update
DELETE /projects/:project_id/orderlines/:orderline_id/packages/:id(.:format)
your form_tag code is update_multiple_project_orderline_packages_path
I think it should be update_multiple_project_orderline_package_path(project_id, orderline_id, package_id)
I am not 100% sure with my statement above, because you gave scrambled Rails Routes, hard to read
and your form action seems goes to packages#edit_multiple controller
so paste your edit_multiple method, not create method
are you implementing your scenario above with javascript, or just plain HTML?

Having an issue with strong params during mass assignment

I'm trying to update multiple records with one form:
Here's the code in the view:
<%= form_for :product, :url => admin_products_update_multiple_path, :html => { :method => :put } do %>
<table>
<tr>
<th>Supplier Name </th>
<th>Product Name </th>
<th>type_name</th>
<th>brand</th>
<th>image</th>
</tr>
<% #products.each do |product| %>
<%= fields_for "product[]", product do |product_fields| %>
<tr>
<td><%= product.supplier_name %> </td>
<td><%= product.subcategory_name %> </td>
<td><%= product_fields.text_field :type_name %></td>
<td><%= product_fields.text_field :brand %></td>
<td><%= product_fields.text_field :image %></td>
</tr>
<% end %>
<% end %>
</table>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
... and here's the controller action I'm calling to update:
def update_multiple
params['product'].keys.each do |id|
#product = Product.find(id.to_i)
#product.update_attributes(product_params)
end
flash[:notice] = "Update products successfully"
redirect_to(admin_products_path)
end
private
def product_params
params.require(:product).permit(:id, :type_name, :brand, :image)
end
When I run the method, I'm getting a 'Unpermitted parameters' error showing all the ids it's trying to update. Any ideas? Thanks in advance!

checkboxs in a table created via form_for

I'm new to RoR so apologies if the answer is super simple. I'm trying to create a table that allows users to select other users that can collaborate on a wiki. The issue I'm having is that no matter which checkbox you select on the table. It only toggles the topmost option.
here is the code in question:
<%= form_for [#wiki, #wiki.collaborators.build] do |f| %>
<table class="bordered hoverable">
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td class="right-align"><%= f.check_box :user_id %><%= f.label :user_id, "Give Access" %></td>
</tr>
<% end %>
</tbody>
</table><br /><br />
the controller values in new
def new
#wiki = Wiki.find(params[:wiki_id])
#collaborator = Collaborator.new
#users = (User.all - [current_user])
end
The problem here is that through check_box's you can't get more than one user selected. In order to select multiple data, you need to use f.collection_select.
Here's how:
<%= f.collection_select :user_id, #users, :id, :name, {prompt: "Please select collaborators"}, {multiple: true} %>
To select multiple the the name of the checkbox should not be :user but contain the user id. Try something like that:
<%= form_for [#wiki, #wiki.collaborators.build] do |f| %>
<%= f.fields_for :collaborators do |c| %>
<table class="bordered hoverable">
<tbody>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td class="right-align"><%= c.check_box user.id %><%= f.label user.id, "Give Access" %></td>
</tr>
<% end %>
</tbody>
</table><br /><br />
<% end %>
<% end %>
The controller would then recieve params like that:
{:collaborators => {1 => '0', 2 => '1'}
showing that user with id 1 was not checked, user with id 2 was checked

How to setup the actions with considering database design of rails3

Assume you have the model called 'Topic' as a parent, and 'Comment' as a child.
On the url 'topics/show/35' you can see all the comments that belongs to this topic ID#35.
When logged-in user want to post his new comment at this page,
should I write 'comment_create' action in topics_controller.rb?
or just write 'create' action in comments_controller.rb, and call it from this page?
Which one is regular way??
If I call 'create' action in comments_controller, how can I write in view to pass
'Model name' to add comments into
'Models ID#'
'comment body'
or should I just write actions separately like this?
controllers/comments_controller.rb
def create_in_topic
code here! to add new comment record that belongs to topic....
end
def create_in_user
code here! to add new comment record that belongs to user....
end
for your information, comment adding action should be something like this.
def create
#topic = Topic.find(params[:topics][:id] )
#user_who_commented = current_user
#comment = Comment.build_from( #topic, #user_who_commented.id, params[:topics][:body] )
#comment.save
redirect_to :back
flash[:notice] = "comment added!"
end
Example Updated!!!
views/topics/show.html.erb
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #topic.comment_threads.each do |comment| %>
<tr>
<td><%= comment.id %></td>
<td><%= comment.title %></td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td> **Comment destroy method needed here!!!** </td>
</tr>
<% end %>
</table>
<%=form_for :topics, url: url_for( :controller => :topics, :action => :add_comment ) do |f| %>
<div class="field">
<%= f.label :'comment' %><br />
<%= f.text_field :body %>
</div>
<%= f.hidden_field :id, :value => #topic.id %>
<div class="actions">
<%= f.submit %>
<% end %>
controllers/topics_controller.rb
def add_comment
#topic = Topic.find(params[:topics][:id] )
#user_who_commented = current_user
#comment = Comment.build_from( #topic, #user_who_commented.id, params[:topics][:body] )
#comment.save
redirect_to :back
flash[:notice] = "comment added!"
end
I think the most straight forward implementation it's going to be an action (ie: add_comment) in your Topic Controller. Once the view call the TopicController#add_comment action you will have all your Topic information and also the comment data so you can easily add the comment to the Topic from there.
Let me know if you need further help.
FedeX
Well I'm not to sure because that gem, but you could try something like this:
<%=form_for #topic, url: url_for( :controller => :topics, :action => :add_comment ) do |f| %>
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #topic.comment_threads.each do |comment| %>
<%= f.fields_for :comment_threads, comment do |comment_form| %>
<tr>
<td><%= comment.id %></td>
<td><%= comment.title %></td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>Delete? <%= comment_form.check_box :_destroy %></td>
</tr>
<% end %>
<% end %>
</table>
<div class="field">
<%= f.label :'comment' %><br />
<%= f.text_field :body %>
</div>
<%= f.hidden_field :id, :value => #topic.id %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Let me know if it helps you! FedeX

html5 in rails3 views

I have a view with some embedded ruby in it... i want to insert a cell <td></td> into it, but when i do that it gives several error messages? This is because i concatenate a text field and a submit button into the embedded ruby.
This is my code:
<table>
<% for answer in #question.answers %>
<tr>
<!-- this displays all the possible answers -->
<td>
<%= answer.text %>
</td>
<% if current_user.can_vote_on? (#question) %> <!-- if a current user has not yet voted.. -->
<td> <%= form_tag('/vote', :method => "post") do
hidden_field_tag('vote[answer_id]', answer.id) +
submit_tag("Vote")
end %> <!-- vote button.. -->
<% end %>
</td>
</tr>
<% end %>
<% if current_user.can_vote_on? (#question) %> <!-- this shows a answer text field -->
<tr>
<td>
<%= form_tag('/vote/new_answer', :method => "post") do
hidden_field_tag('answer[question_id]', #question.id) +
hidden_field_tag('answer[user_id]', current_user.id) +
text_field_tag('answer[text]') + <!-- in here i want an extra </td><td> tag -->
submit_tag('Vote')
end %>
</td>
</tr>
<% end %>
My question is: how can i exit the embedded ruby and at the same time staying in the concatenated string...? I want to add the </td> and the <td> after the text_field_tag('answer[text]')
I tried this:
<td>
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag('answer[question_id]', #question.id) %>
<%= hidden_field_tag('answer[user_id]', current_user.id) %>
<%= text_field_tag('answer[text]') %>
</td>
<td>
<%= submit_tag('Vote') %>
<% end %>
</td>
And it works!
Thijs
Simple answer: It's not possible.
I suggest you try a different approach such as using divs inside your td elements. If I were you I wouldn't concatinate the strings together.
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag(answer[question_id], #question.id %>
... so on ...
<div class="position_it_somewhere_with_this_class"><%= submit_tag("vote") %></div>
<% end %>
You don't concatenate tags!
Also you don't use divs in table rows. put the classes in your tds
...
<%= form_tag('/vote/new_answer', :method => "post") do %>
<%= hidden_field_tag('answer[question_id]', #question.id) %>
<%= hidden_field_tag('answer[user_id]', current_user.id) %>
<%= text_field_tag('answer[text]') %>
<%= submit_tag('Vote') %>
<% end %>
</td>
</tr>
..

Resources