Updating multiple tables in one form in Rails 2.3.x - ruby-on-rails

Seems there should be a super-quick Railsy way to do this, but excessive Googling has yielded nothing to clear things up.
OK. I need to update three tables from one form. The view part of the equation is well-documented (form_for, fields_for). But I'm unsure how to handle the form params that are sent to the update action in the parent controller. Note: The three tables all have a defined Rails association.
View:
<% form_for #account do |a| %>
<table>
<tr class="odd">
<td>
<%= a.label :plan_id %>
</td>
<td>
<%= a.text_field :plan_id %>
</td>
</tr>
<tr class="even">
<td>
<%= a.label :company %>
</td>
<td>
<%= a.text_field :company %>
</td>
</tr>
<% fields_for #user do |u| %>
<tr class="odd">
<td>
<%= u.label :first_name %>
</td>
<td>
<%= u.text_field :fname %>
</td>
</tr>
<tr class="even">
<td>
<%= u.label :last_name %>
</td>
<td>
<%= u.text_field :lname %>
</td>
</tr>
<tr class="odd">
<td>
<%= u.label :email %>
</td>
<td>
<%= u.text_field :email %>
</td>
</tr>
<tr class="even">
<td>
<%= u.label :phone %>
</td>
<td>
<%= u.text_field :phone %>
</td>
</tr>
<tr class="odd">
<td>
<%= u.label :title %>
</td>
<td>
<%= u.text_field :title %>
</td>
</tr>
<% end %>
<% fields_for #site do |s| %>
<tr class="even">
<td>
<%= s.label :domain %>
</td>
<td>
<%= s.text_field :domain_name %>
</td>
</tr>
<tr class="odd">
<td>
<%= s.label :url %>
</td>
<td>
<%= s.text_field :url %>
</td>
</tr>
<% end %>
<tr>
<td colspan="2">
<%= a.submit :submit %>
</td>
</tr>
</table>
<% end %>
Update action of accounts controller (This doesn't work):
account = params[:account]
user = account
site = account
account.save!
user.save!
site.save!
How do I handle the params that are posted to the update action? It seems straightforward to create new records in three tables from one form, but I don't know how to update those same three tables from the same form.

If accounts/users/sites are all related then your associations in your model will handle the "tables" for you. You should be thinking about your problem in terms of models (ie: your domain/business problem). Let's say that one user can have multiple accounts (otherwise, no point in the account model) and each account can own a site (web hosting management app?).
If you set up your associations in app/models/*.rb with the has_many etc relationships, the saving a form in the controller method (or in IRB) is pretty easy. The controller code you have is not right at all. You can't assign variables like that and expect Rails to do quite that much magic.
account.user = params[:user]
account.site = params[:site]
For nested forms. If you can't get that to work, use rails c:
account = Account.new
user = User.new
site = Site.new
account.user = user
account.site = site
account.save # will fail if you have constraints/validations
Get it to work in rails c and IRB and then look at your form and HTTP activity using Firebug or other browser tool. Put this in your controller method puts params and you'll see how nested forms post.

Related

Rails: How to access two models in a single loop

I am using Audited gem to track the changes done on users. What I want to display exactly is the changes made which is the audits with the time they are updated at in a same row.I tried to display it this way but it makes repetitions.
<% #users.each do |user| %>
<% user.audits.each do |audit| %>
<% if audit.action != "create" %>
<% user.revisions.each do |revision| %>
<tr class="list-item">
<td>
<%= user.role %>
</td>
<td>
<%= audit.action %>
</td>
<td>
<%= audit.audited_changes %>
</td>
<td>
<%= revision.created_at %>
</td>
<td>
<%= revision.updated_at %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
<% end %>
What I want is to be able to display them with out displaying a single change multiple times.
I am looking for an expression like
for(i=5,j=3;j<5;i++,j++){
....
}
in rails, to avoid the repetition. Thank you
I solved it this way since both audits and revision has same number of elements.I hope it helps for the others.
<% #users.each do |user| %>
<% user.audits.each_with_index do |audit, i| %>
<% if audit.action != "create" %>
<% user.revisions[i] %>
<tr class="list-item">
<td>
<%= user.role %>
</td>
<td>
<%= audit.action %>
</td>
<td>
<%= audit.audited_changes %>
</td>
<td>
<%=user.revisions[i].created_at %>
</td>
<td>
<%= user.revisions[i].updated_at %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
You could also try zip:
user.audits.zip(user.revisions) do |audit, revision|

Submit a form to execute the UPDATE action from within the index

I'm trying to create a feature that allows users to edit a Client entry directly from the index page. When the user clicks 'Edit', a partial is rendered which replaces the elements with input text fields. But when the 'Update client' button is pressed, I get the error:
"No route matches [POST] "/clients/27"
I'm able to create new clients and destroy clients directly from the index... what am I doing wrong with the update action?
The partial:
<tr id="test">
<%= form_for Client.find(27), :method => :PUT do |f| %>
<td class="input">
<%= f.text_field :name, :value => "Test" %>
</td>
<td class="input">
<%= f.text_field :company %>
</td>
<td class="input">
<%= f.text_field :email %>
</td>
<td class="grayedOut"></td>
<td class="actions">
<%= f.submit "Confirm edit" %>
</td>
<% end %>
</tr>
routes.rb file:
resources :clients do
resources :projects do
resources :items
end
end
I figured it out. For whatever reason, nesting a form inside of a table seems to mess up the way form submits. When I rendered the partial outside of the table, the form had no problem submitting the update action.
I'm still confused as to WHY this happening. My solution to this problem is to use divs instead of tables.
EDIT: OK, so I researched this topic a bit more and found out that 'forms' are not valid children of <table> or <tr>. To fix this problem, I put the <%= form_for %> tag inside of the first <td>, and the <% end %> tag inside of the last <td>. Now it's working perfectly! Here's what my partial looks like now:
<tr id="test">
<td class="input">
<%= form_for Client.find(27), :method => :PUT do |f| %>
<%= f.text_field :name, :value => "Test" %>
</td>
<td class="input">
<%= f.text_field :company %>
</td>
<td class="input">
<%= f.text_field :email %>
</td>
<td class="grayedOut"></td>
<td class="actions">
<%= f.submit "Confirm edit" %>
<% end %>
</td>
</tr>

Accept Nested Attributes not working as expected

So I have an entity form that accepts nested attributes for another entity. This renders perfectly fine. However, the nested form is not functioning as I would like it to. See below:
<table class="datagrid">
<thead class="datagrid">
<th width="300" align="left"> Item</th>
<% unless current_user.is_partner? %>
<th width="100"> Location</th>
<% end %>
<th> Amount Requested</th>
<th> Amount Checked Out</th>
</thead>
<% session[:clicked_request].items.each do |item| %>
<tr class="<%= cycle('dg_list_line_odd', 'dg_list_line_even') %>">
<td> <%= link_to "#{item.name}", item_path(item) %></td>
<% unless current_user.is_partner? %>
<td> <%= item.location.name %></td>
<% end %>
<td> <%= item.requested %></td>
<td><%= f.text_field :amount, :value => item.requested, :size => 1 %></td>
</tr>
<% end %>
</table>
<p> </p>
As you can see there is an "each" loop here, that allows for the display, and hopefully the creation, of multiple items. However, when I press the submit button, regardless of how many items are present, only one of them is created.
Your suggestions are much appreciated.
That's not how you render forms with accepts_nested_attributes
Assuming f is a form builder bound to the parent object, you need to do something like
<%= f.fields_for :items do |item_form| %>
<%= item_form.text_field :amount
<% end %>
The block will be executed once for each item in the collection. In addition, item_form is setup with the right prefix for the controller side to work properly.

select within loop in Rails 3, taking only first option

Guys I have a form like this
<%= form_tag({:action => 'update_survey_list_status') do%>
<table id="survey_form">
<tr>
<th>Beneficiary Details</th>
<th>HFI details</th>
<th style="vertical-align: middle">
<input type='checkbox' name='checkall' onclick='checkedAll();'></th>
</tr>
<% #to_be_registred_list.each do |b| %>
<tr>
<td style="vertical-align: middle"><b> <%= b.name %></b><br />
<span><%= b.age %>, <%= b.sex %><br /><%= b.address %></span>
</td>
<td style="vertical-align: middle">
<%= select("beneficiaryloans","hfi_id",
Beneficiary.find(b.beneficiary_id).beneficiaryloans.collect
{
|h| [User.find(h.hfi_id).name+" - Rs. #{h.amount} # #{h.rate} % for
#{h.period}", h.hfi_id] }) %>
</td>
<td> <%= check_box_tag "benificiary_loan_ids[]", b.beneficiary_id,:name =>
"benificiary_loan_ids[]"%>
</td>
</tr>
<% end %>
</table>
<%end %>
Here, within a form, #to_be_registred_list will return 2 records, for each |b| record, within a select tag
Beneficiary.find(b.beneficiary_id).beneficiaryloans.collect will return many records. so each drop-down filled with associated values. here if I submits the form, even after selecting different records from each drop-down, it will only takes first option from each drop-down. how to solve this?
I need what I selected form each drop-down!
Did you used the debug on rails?
Use it and check the params you're receiving

Rails form processing

I have a form with a store number (collection select box), date (3 select boxes), and a list of items with a quantity field beside each item. I have been able to pass the items and quantities as an array of hashes, but I can't get the date and store numbers in because I can't seem to change their name to include the [].
Here's the code
<% form_for(#credit) do |f| %>
<% stores = Store.find(:all, :conditions => { :active => true }, :order => :storeNum) %>
Store Number<%= f.collection_select :storeNum, stores, :storeNum, :storeNum %>
<br /><%= f.date_select :credDate %>
<table>
<tr>
<th>Quanity</th>
<th>Item Number</th>
<th>Name</th>
</tr>
<% #items.each do |item| %>
<tr>
<td>
<%= f.text_field ( :quantity, :name => "credit[][quantity]", :size => 3 ) %>
<%= f.hidden_field :item, :name => "credit[][itemNum]", :value => item.itemNum %>
</td>
<td><%=h item.itemNum %></td>
<td><%=h item.name %></td>
</tr>
<% end %>
<tr><td colspan="3">
<%= f.submit 'Submit' %></td>
</tr>
</table>
<% end %>
Any help is surely appreciated. I've been working on this two days.
Have you considered simple HTML inputs?
<input type="text" name="credit[][quantity]" size="3" id="quantity"></input>

Resources