Nested forms rails field does not update - ruby-on-rails

I am trying to do nested forms like mentioned here.
http://guides.rubyonrails.org/form_helpers.html#nested-forms
The goal is as follows: I have multiple colli with one checkbox which can be checked. The colli list can be deleted or modified but the checks and their information need to stay.
Model
class Colli < ActiveRecord::Base
has_one :check, foreign_key: "subcontainerid", primary_key: "colliid"
accepts_nested_attributes_for :check, allow_destroy: true
end
class Check < ActiveRecord::Base
belongs_to :colli
end
So every colli has one check. The colliid from the colli table created a link with the check table using the subcontainer id.
Controller
Within the colli controller I whitelist the check_attributes.
def colli_params
params.require(:colli).permit(:colliid, :collinaam, check_attributes: [:id, :checked])
end
Form
My form looks like this.
<%= form_for(#colli) do |f| %>
<% if #colli.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#colli.errors.count, "error") %> prohibited this colli from being saved:</h2>
<ul>
<% #colli.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.fields_for :checks do |checks_f| %>
<p>check start</p>
<div class="field">
<%= checks_f.label :checked %><br>
<%= checks_f.check_box :checked %>
</div>
<% end %>
<div class="field">
<%= f.label :colliid %><br>
<%= f.text_field :colliid %>
</div>
<div class="field">
<%= f.label :collinaam %><br>
<%= f.text_field :collinaam %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If I do form_for :check I can't see the checkboxes. When I do form_for :checks I see a checkbox but it does not work. When clicking submit I see following error:
undefined method `checked' for nil:NilClass
<p>
<strong>Checked:</strong>
<%= #colli.check.checked %>
</p><p>
<strong>Collinaam:</strong>
<%= #colli.collinaam %>
Which means it did not get saved. Does anybody know how to fix this?

Try adding this to your form-
<%= f.fields_for :checks, #colli.check.build do |checks_f| %>
<p>check start</p>
<div class="field">
<%= checks_f.label :checked %><br>
<%= checks_f.check_box :checked %>
</div>
<% end %>

Related

How to create a view containing field of an associated model in rails?

In my project, I have an Organization model and an Address model. Here is the association beetween the models:
class Organization < ApplicationRecord
belongs_to :adresse
end
class Organization < ApplicationRecord
has_one :organization
end
I would like to know how to create a new form and include attributes from both model. For the moment, my organization/new.html.erb look like this:
<%= form_with(model: organization, local: true) do |form| %>
<% if organization.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(organization.errors.count, "error") %> prohibited this organization from being saved:</h2>
<ul>
<% organization.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :organizationName%>
<%= form.text_field :organizationName, id: :organization_organizationName %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email, id: :organization_email %>
</div>
<div class="field">
<%= form.label :website %>
<%= form.text_field :website, id: :organization_website %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
And I tried to add this to the form but address method is not recognized:
<div class="field">
<%= form.label :streetNumber %>
<%= form.text_field :organization.address.streetNumber%>
</div>
In controller, I have access to the address of the organization like:
#organization.address.streetNumber
PS: I'm new to Rails ;)
That's what fields_for is for.
<%= form_for #person do |person_form| %>
First name: <%= person_form.text_field :first_name %>
Last name : <%= person_form.text_field :last_name %>
<%= fields_for :permission, #person.permission do |permission_fields| %>
Admin? : <%= permission_fields.check_box :admin %>
<% end %>
<%= person_form.submit %>
<% end %>

Nested Resources in show template

I'm having trouble understanding nested resources. There is a Service scaffold, and there is Symptom model. I wanted to be able to add the symptom_item string to the service scaffold.
This is my current show template code:
<% if #service.symptoms.any? %>
<% #service.symptoms.each do |symptom| %>
<li><%= symptom.symptom_item %></li>
<% end %>
<% else %>
<p>
none
</p>
<% end %>
Here is my form code:
<%= form_for(#service) do |f| %>
<% if #service.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#service.errors.count, "error") %> prohibited this service from being saved:</h2>
<ul>
<% #service.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :s_text %><br>
<%= f.text_area :s_text %>
</div>
<div class="field">
<%= f.label :img_text %><br>
<%= f.text_field :img_text %>
</div>
<%= f.fields_for :symptoms do |builder| %>
<div class="field">
<%= builder.label :symptom_item %><br>
<%= builder.text_field :symptom_item, :rows => 3 %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here is my controller code that allow the symptom_attributes:
def service_params
params.require(:service).permit(:name, :s_text, :img_text, symptom_attributes: [:id, :service_item])
end
I know the problem is in the show template. When I write something as simple as:
= #service.symptoms
it gives me something funky like this:
#<Symptom::ActiveRecord_Associations_CollectionProxy:0x000000095295c8>
Does anyone see what's wrong with my code in the show template or maybe some where else?
Here are my models just in case:
class Service < ActiveRecord::Base
has_many :symptoms
accepts_nested_attributes_for :symptoms, allow_destroy: true
end
class Symptom < ActiveRecord::Base
belongs_to :service
end
It should be symptoms_attributes instead of symptom_attributes and symptom_item instead of service_item in your strong parameters
def service_params
params.require(:service).permit(:name, :s_text, :img_text, symptoms_attributes: [:id, :symptom_item])
end

Why my textbox shows ActiveRecord_Associations_CollectionProxy in form

I'm building rails application and I use form_for to render the form. Everything works fine works fine except one text field has ActiveRecord_Associations_CollectionProxy inside the text which I'm not sure where it's coming from.
Here's my form
<%= form_for(#video, html: { class: "directUpload" }, multipart: true) do |f| %>
<% if #video.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #video.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :path %><br>
<%= f.file_field :path%>
</div>
<div class="field">
<%= f.label :tags %><br>
<%= f.text_field :tags %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And here's my Video model
class Video < ActiveRecord::Base
belongs_to :user
has_many :video_tags
has_many :tags, through: :video_tags
end
Here's the screenshot
You have multiple tags that you want show in form. Your controller could serve all tags for form where you could show them with http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/options_from_collection_for_select for example.

Rails has many through not working

I've got 3 models:
Vacancy
has_many :address_vacancies
has_many :addresses, through: :address_vacancies
Address
has_many :address_vacancies
has_many :vacancies, through: :address_vacancies
AddressVacancy
belongs_to :address
belongs_to :vacancy
and in my form I use the following code:
<%= f.collection_select :address_id, Address.order("CREATED_AT DESC"),:id,:title, include_blank: true %>
which throws an error: undefined method address_id', why is that and what am I doing wrong?
Edit
The full form looks like this:
<%= form_for(#vacancy) do |f| %>
<% if #vacancy.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#vacancy.errors.count, "error") %> prohibited this vacancy from being saved:</h2>
<ul>
<% #vacancy.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :address %>
<%= f.collection_select :address, Address.order("CREATED_AT DESC"),:id,:title, include_blank: true %>
</div>
<div class="field">
<%= f.label :signup_until %><br>
<%= f.date_select :signup_until %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This:
<div class="field">
<%= f.label :address %>
<%= f.collection_select :address, Address.order("CREATED_AT DESC"),:id,:title, include_blank: true %>
</div>
Isn't valid in the context of a Vacancy form (from the form_for #vacancy) since a Vacancy doesn't have a single address attribute. It has a collection of addresses through the has_many association. It would also be invalid to use :address_id for the same reason.
If you want to edit the various addresses for the one vacancy, you would need a subform. You'd use accepts_nested_attributes_for in the model, and fields_for in the view.
<%= form_for #vacancy do |f| %>
...
<%= f.fields_for :addresses do |af| %>
...
<!-- Here you'd render a partial or a set of inputs for this address %>
<%= af.input :street %> <!-- e.g., if there's a street attribute for Address -->
...
<% end %>
...
<% end %>

Passing User_ID through new_item form

I have a simple app that allows users to create 'items'. On the _form, the only data that it asks for is 'content' and 'user_id', which is currently a number picker that assigns user_id to the item for ownership. But what I want to do is have the form assume that the user_id is the current user's ID (using Devise). That way other people can't assign 'items' to other users. Make sense? Here's the form.
_form.html.erb
<%= form_for(#item) do |f| %>
<% if #item.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#item.errors.count, "error") %> prohibited this item from being saved:</h2>
<ul>
<% #item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_field :content %>
</div>
<div class="field">
<%= f.label :user_id %><br />
<%= f.number_field :user_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You should be working with associations from the model.
example your Items model should have belongs_to :user
then your would just use the :user method not the user_id attribute.
But you really could make this much more simpler.
install simple_forms gem it will make your life easier.
gem "simple_form"
then
<%= simple_form_for(#item) do |f| %>
<%= f.input :content %>
<%= f.association :user %>
<%= f.button :submit %>
<% end %>

Resources