Rails delete multiple objects checkboxes with fields_for - ruby-on-rails

I have two models - Campaigns & Cities (belongs to Campaign). On the create and edit form for Campaign I'm using fields_for to allow users to edit cities directly on the campaign edit page. I want to add a checkbox for each city, so that their ids will be sent in an array (delete_cities) in the params.
My attempt at it:
<%= f.fields_for :cities do | city_form | %>
<%= city_form.label :name %>
<%= city_form.text_field :name%>
<%= city_form.label :phone_number %>
<%= city_form.text_field :phone_number %>
<%= city_form.label :zip_code %>
<%= city_form.text_field :zip_code %>
<%= city_form.check_box :delete_cities %>
</br>
<% end %>
I cant solve this any help is appeciated.

According to the docs:
:allow_destroy
If true, destroys any members from the attributes hash with a _destroy key and a value that evaluates to true (eg. 1, '1', true, or 'true'). This option is off by default.
In order to allow users to delete cities, you can do like this:
<%= city_form.check_box :_destroy %>
And don't forget to permit :_destroy in the controller:
params.require(:campaign).permit(cities_attributes: [:id, :_destroy])

Related

How to pass an array of string through the rails' form

I have a trouble with the rails' form, I need to pass to the form of Event an array of emails, I have this attribute members that I want to have like array. I try in this way but it doesn't work, can you help me?
<div class="field">
<%= form.fields_for :members do |p| %>
<% #group.list_accepted.each do |part| %>
<%= p.label :email , User.find(part.user_id).username %>
<%= p.check_box :email, {} ,User.find(part.user_id).email, nil %>
<br>
<%end%>
<% end %>
</div>
params.require(:event).permit(:title, :description,:user_id, :group_id, :start_date, :end_date, members: [:email])
the result of this is a set with just the first email {email=> "email#.com"}

HABTM association dropdown select

I am trying to create a dropdown select on a form. I have a HABTM association between professors and classrooms:
Classroom Model:
class Classroom < ApplicationRecord
has_and_belongs_to_many :professors
end
Professor Model:
class Professor < ApplicationRecord
has_and_belongs_to_many :classrooms
end
Strong Params:
def classroom_params
params.require(:classroom).permit(:name, :professor_ids => [])
end
I am trying to find a way to use f.select instead of select_tag inside the form. But when I do it, the database does not save the values. This way works:
<%= form_for #classroom do |f| %>
<%= f.label :name %><br>
<%= f.text_field :name %><br>
<% array = Professor.all.map { |professor| [professor.user.name, professor.id] } %>
<%= select_tag "classroom[professor_ids][]", options_for_select(array) %>
<% end %>
But I am trying like that and it is not working:
<%= form_for #classroom do |f| %>
<%= f.label :name %><br>
<%= f.text_field :name %><br>
<% array = Professor.all.map { |professor| [professor.user.name, professor.id] } %>
<%= f.select :professor_ids, options_for_select(array) %>
<% end %>
The view works correctly but when I submit the form, the value doesn't go to to the classroom_params. I tried to debug it stopping the controller after the submit and I got this:
The params came correctly with all the information submitted, but the classroom_params came missing the professor_ids.
Is there a way to do this dropdown using f.select?
You whitelisted the array of 'professor_ids', but your 'select' input returns 1 string ("prefessor_ids" => "2" from you screenshot). Maybe you want to set the select as 'multiple'? (I have not tested it, but i think params will be whitelisted correctly after that)
<%= form_for #classroom do |f| %>
<%= f.label :name %><br>
<%= f.text_field :name %><br>
<%= s.collection_select :professor_ids, Professor.all, :id, :name, multiple: true %>
<% end %>
where
class Professor
...
delegate :name, to: :user
end
Update
You probably don't have 'cfg' variable in your controller action.

Rails: How to customise the order of fields in a form with nested fields

I have a form that saves attributes to two models Company and nested model Address in a single form using simple_nested_form_for and simple_fields_for.
The attributes:
Company:
-legal form
-uploads
Address:
-name
-website
In my form I wish to change the order of the fields
-name (Address model)
-legal form (Company model)
-website (Address model)
-uploads (Company model)
thus interchanging the form attributes and nested_field attributes
I tried the following, but that did not seem to work.
<%= simple_nested_form_for #company do |f| %>
<%= f.simple_fields_for :address do |c| %>
<%= c.input :name %>
<% end %>
<%= f.input :legal_form %>
<%= f.simple_fields_for :address do |c| %>
<%= c.input :website %>
<% end %>
<%= f.input :uploads %>
<% end %>
How do I make this work?
While it doesn't look like all your attributes line up ( you said uploads was address and website was in company in your attributes list but the form doesn't match that ) there is still a simple solution to your question.
Nested fields rely on their builder to denote which part of the params hash to put them in. So simply call the builder that you need.
<%= simple_nested_form_for #company do |f| %>
<%= f.simple_fields_for :address do |c| %>
<%= c.input :name %>
<%= f.input :legal_form %>
<%= c.input :website %>
<%= f.input :uploads %>
<% end %>
<%= f.submit %>
<% end %>
In each place that you need the company fields, you'll call builder f and in each place you need the address fields, you'll call builder c - but nested them all inside the lowest common denominator so they're all available.

Rails Nested Resources - Many Objects, Same Model, One Form Without Existing Objects

I have a model Vendors which has many Products. I would like to add many Products at a time without showing the existing products that belong to the vendor.product relationship. I only want to display the form for new objects. Currently everything is working but on the add page I am getting all of the objects that are tied to the instance relationship which is #vendor.products. If I do not use that relationship in the form I do not get any fields.
Here is my new Product action:
'def new
#vendor = Vendor.find(params[:vendor_id])
5.times {#vendor.products.build}
end'
Here is my form:
<%= form_for #vendor do |f| %>
<%= f.fields_for :products do |g| %>
<p>
<%= g.label :name %>
<%= g.text_field :name %>
<%= g.label :category %>
<%= g.select :category, options_for_select(['Parts', 'Labor', 'Extras', 'Shop']) %><br>
</p>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
The Product Model:
class Product < ActiveRecord::Base
belongs_to :vendors
attr_accessible :name, :category, :vendor_id, :vendor_sku, :products
validates :name, :uniqueness => true
validates :category, :presence => true
validates :name, :presence =>true
end
Just to reiterate, I would only like to show the blank, newly built objects as opposed to all of the products tied to that #vendor 's relationship. I must be overlooking a form structure to get this done but I just have not been able to figure it out. Thanks for looking.
Only render the nested fields if the product in a new record.
<%= form_for #vendor do |f| %>
<%= f.fields_for :products do |g| %>
<% if g.object.new_record? %>
<p>
<%= g.label :name %>
<%= g.text_field :name %>
<%= g.label :category %>
<%= g.select :category, options_for_select(['Parts', 'Labor', 'Extras', 'Shop']) %><br>
</p>
<% end %>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>

Rails way to edit multiple attributes on a model from a view

I have a model Person with the following attributes:
:name, :state, :age, :town
Let's say I want to be able to edit all of the attributes except for :name from that Person's edit view. Is there a "rails" way to do this, and if so what would I write without looping through each attribute and creating a form?
Right now, I've got something like this:
<%= form_for #person do |person_form| %>
<%= person_form.fields_for :age do |age_form| %>
<%= age_form.text_field :age %>
<% end %>
<% end %>
And I would do that for each attribute.
It would be just a standard form since the object you're wrapping the form around has all of the attributes.
<%= form_for #person do |f| %>
<%= f.text_field :state %>
<%= f.text_field :age %>
<%= f.text_field :town %>
<%= f.submit %>
<% end %>
Of course, you can add labels and whatever else you need to the form.

Resources