Ruby on Rails - simple_form fields_for create different index - ruby-on-rails-3

I have a question about updating one-to-many fields using simple_form field_for method
I have 2 models, Company and Clients, which has a one-to-many relationship.
I displayed clients using field_for, but for UI reason, I had to called it twice.
But for some reason, the index of the input fields was given a different value. Below is my code
<%= simple_form_for #company do |f| %>
<table>
<tr>
<td>
<%= f.input :name, label: 'Company name: ' %>
<%= f.simple_fields_for :clients do |client| %>
<%= client.input :name, label: 'Client names: ' %>
<% end %>
<%= f.input :info, label: 'Company info: ' %>
</td>
<td class="span2 clients_desc">
<%= f.simple_fields_for :clients do |client| %>
<%= client.input :description, label: 'Client description: ' %>
<% end %>
</td>
</tr>
</table>
<% end %>
Say if I had 3 clients, the output for the name of the input fields became
company[client_attributes][0][name], company[client_attributes][1][name], company[client_attributes][2][name]
and
company[client_attributes][3][description], company[client_attributes][4][description], company[client_attributes][5][description]
This result in duplicating clients during store. How do I solve this?

An easy workaround would be "caching" the form fields like so:
# ...
<%= f.simple_fields_for :clients do |client| %>
<%= client.input :name, label: 'Client names: ' %>
<% client_description_input = client.input :description, label: 'Client description: ' %>
<% end %>
# ...
<%= client_description_input %>
# ...

Related

How to save to two tables from one form in Rails

I have a regular form for User information which starts like so:
<%= form_for(#user, :html => { :class => "form-horizontal" }) do |f| %>
<%= f.text_field :last_name %>
...
<%= f.submit "Submit", class: "btn btn-primary", :name => "submit_button" if #user.last_step? %>
<% end %>
I also have some non User fields in the form. Here's an example:
<%= f.label "When is your birthday?" %>
<%= select_tag "month" %>
<%= select_tag "day" %>
<%= select_tag "year" %>
How would I save this to a different table than User?
If you want to update a model other than User, you should probably use accepts_nested_attributes_for and fields_for. The alternative is to just do the work in your create action of your UsersController, ie:
def create
#user = User.create params[:user]
#foo = Foo.find params[:foo_id]
#foo.date = Date.new(params[:foo_year], params[:foo_month], params[:foo_day])
...
end

Rails 3 - Ransack - check_box_tag

Listing Model - belongs_to :area
Area Model - has_many :listings
I'm trying to implement a search using Ransack with check boxes; where user checks selected areas, search returns all the listings of the areas selected.
<%= search_form_for #search do |f| %>
<% areas = Area.all %>
<% areas.each do |area| %>
<%= check_box_tag('q[area_id_eq][]', area.id) %>
<%= area.location%>
<% end%>
<%= f.submit "SEARCH" %>
<% end %>
Console output:
Parameters: {"utf8"=>"✓", "q"=>{"area_id_eq"=>["1", "2"]}, "commit"=>"SEARCH"}
Completed 500 Internal Server Error in 4ms
NoMethodError - undefined method `to_i' for ["1", "2"]:Array:
Just not sure how to implement it to accept multiple check box values.
Instead of using "area_id_eq", use "area_id_any". You'll also want to check to make sure that your parameters are selected:
<%= search_form_for #search do |f| %>
<% areas = Area.all %>
<% areas.each do |area| %>
<%= check_box_tag('q[area_id_eq_any][]', area.id, (params[:q][area_id_eq_any].include? area.id.to_s) ? true : false ) %>
<%= area.location%>
<% end%>
<%= f.submit "SEARCH" %>
<% end %>

Update form in rails - No route matches [PUT]

I have a form to create adverts.
Controllers:
def edit
#engines = Engine.all
#car = Car.find(params[:id])
end
def update
#car = Car.find(params[:id])
if #car.save
redirect_to root_path
end
end
My routes:
resources :adverts
Create.html.erb
<%= form_for #car, :url => adverts_path do |f| %>
<div><%= f.label :name %><br />
<%= f.text_field :name %></div>
<%= hidden_field_tag :model_id, params[:model_id] %>
<%= select_tag :engine_id, options_from_collection_for_select(#engines, "id", "name",:selected=>#car.engine_id) %>
<div><%= f.submit "Create car!" %></div>
<% end %>
I can create advert, but I can't to update it.
edit.html.erb
<%= form_for #car, :url => adverts_path do |f| %>
<div><%= f.label :name %><br />
<%= f.text_field :name %></div>
<%= hidden_field_tag :model_id, params[:model_id] %>
<%= select_tag :engine_id, options_from_collection_for_select(#engines, "id", "name",:selected=>#car.engine_id) %>
<div><%= f.submit "Update car!" %></div>
<% end %>
when I submited my form, I have an error - No route matches [PUT] "/adverts"
$ rake routes:
adverts GET /adverts(.:format) adverts#index
POST /adverts(.:format) adverts#create
new_advert GET /adverts/new(.:format) adverts#new
edit_advert GET /adverts/:id/edit(.:format) adverts#edit
advert GET /adverts/:id(.:format) adverts#show
PUT /adverts/:id(.:format) adverts#update
DELETE /adverts/:id(.:format) adverts#destroy
I need help.
When you are updating you have to let Rails know which object you want to update by passing an id.
In edit.html.erb change:
<%= form_for #car, :url => adverts_path do |f| %>
to:
<%= form_for #car, :url => advert_path(#car) do |f| %>
By the way, I find your code very strange. Why don't your model names match your controllers and routes? I mean you are creating an advert but your model is called car. That doesn't make any sense. Either call it car or advert, but don't mix them.
If you used RESTful routing, you don't need to specify a url, just need:
<%= form_for #car do |f| %>
The form can know #car is new record, or saved record, so it will send appropriate http method.
And in your update action:
def update
#car = Car.find(params[:id])
if #car.update_attributes(params[:car])
redirect_to root_path
end
end
I got myself in a similar situation today with a mismatched resource and model name. I agree the model and controller names need to correlate, but you can override the routes name to be whatever you want.
resources :cars, path: "adverts"
Along with RESTful routing
<%= form_for #car do |f| %>
You may also want to make sure your url: path is singular on the #form_form.

How to select only checked records using check_box_tag?

Guys my check_box_tag looks like as follows
<%= form_tag({:action => 'update_survey_list_status',:projectid=>params[:id], :status=>4}, :id => 'to_be_approved_frm') do %>
<% #publishedlist.each do |b| %>
<%= fields_for "beneficiaryloan[#{b.id}]" do |bloan| %>
<%= bloan.text_field :amount, :class=>'forms_txtbx'%>
<%= bloan.text_field :rate, :class=>'forms_txtbx'%>
<%= bloan.text_field :period, :class=>'forms_txtbx'%>
<% end %>
<%= check_box_tag "benificiary_id[#{b.id}]",b.id,:name => "benificiary_id[]"%>
<% end %>
<%= submit_tag "Approve", :class=>'form_buttons' %>
<% end %>
And in controller, I'm reading all the beneficiary ids like this
params[:beneficiaryloan].each do |key, value|
beneficiary = Beneficiary.find(key) rescue nil
#benefciary_loan=beneficiary.beneficiaryloans.build(value)
#benefciary_loan.beneficiary_id=beneficiary.id
#benefciary_loan.hfi_id=session[:id].to_s
#benefciary_loan.status_id=params[:status]
#benefciary_loan.save if beneficiary
end
What I need is, Inserting all the beneficiary ids to [beneficiaryloans] table which are checked, but in my case it inserting all records even some of them are unchecked.
How to do I select only checked ids?
Try changing your check_box_tag to
<%= check_box_tag "beneficiaryloan[#{b.id}][enabled]", 1, true %>
Then in your controller do the following:
params[:beneficiaryloan].select{|k,v| v.delete(:enabled).to_i > 0 }.each do |k,v|
..
end
Since the enabled attribute has no influence in the model you can just delete it out of the resulting beneficiary_load hashes.

Rails - Using form_for and fields_for, how do you access the sub-object while in the fields_for block?

In my first rails app I'm trying to use form_for and fields_for to create a nested object form. So far so good, but I can't figure out how to access the sub-object while in the fields_for block. I've pre-populated a field in the sub-object with data that I want to show in the user instructions.
Models
Garage:
has_many :cars, :dependent => :destroy
accepts_nested_attributes_for :cars
Car:
belongs_to :garage
Garage Controller
def new
#garage = Garage.new
for i in 1..5
#garage.cars.build :stall_number => i
end
end
_form.html.erb
<%= form_for #garage do |f| %>
<%= f.label :title, "Garage Name" %><br />
<%= f.text_field :title %>
<% f.fields_for :cars do |builder| %>
<p>Enter license for car parked in stall: <%= car.stall_number %></p>
<%= f.label :license, "License #:" %><br />
<%= f.text_field :license %>
<%= end %>
<%= end %>
As you can see, inside the builder block for :cars, I want to show, in my user instructions, the field: car.stall_number (populated in my controller with an integer):
<p>Enter license for car parked in stall: <%= car.stall_number%></p>
I've tried a many different ideas: #car.stall_number, object.car.stall_number, etc. No joy. Multiple searches and a look at the fields_for source code haven't helped my understanding. I would appreciate any guidance.
Update: For clarification, per Dan's suggestion I have tried builder.stall_number but it results in a
NoMethodError: undefined method 'stall_number' for #<ActionView::Helpers::FormBuilder:0x00000102a1baf0>
I just dealt with this today myself.
You can access the object of the fields_for through:
builder.object
where builder is your fields_for form builder object. In your particular case, you can say:
<p>Enter license for car parked in stall: <%= builder.object.stall_number%></p>
That should do it for you!
The way you are trying is does not work because you want to access car without filling that variable for data.
I guess you want to have multiple blocks of stalls, where you can enter license plates. For each stall you will need your own fields_for.
I would suggest something like that:
<%= form_for #garage do |f| %>
<%= f.label :title, "Garage Name" %><br />
<%= f.text_field :title %>
<% for i in 1..5 %>
<% f.fields_for #garage.cars[i] do |builder| %>
<p>Enter license for car parked in stall: <%= builder.stall_number%></p>
<%= builder.label :license, "License #:" %><br />
<%= builder.text_field :license %>
<% end %>
<% end %>
<% end %>
Within the fields_for you need to use the form object you define there, in this case builder. Since the data there are not mapped to the outer form (f), but to the cars object (builder).