Rails - add an array of another class on a form - ruby-on-rails

I apologise if the question is quite simple, I'm fairly new to Rails. I'm building a meal planner application, and am trying to have it so that a user can create a meal, and add items to that meal. E.g. a meal of 'fish & chips' would include the items 'fish' and 'chips'. As I understand it, I think I need a way of creating an array of items on the meal creation form - but how do I do that?
Relevant parts of meal.rb:
has_many :items
accepts_nested_attributes_for :items
and item.rb
belongs_to :meal
What do I need to add to the meal form partial for it to accept an array of items? I apologise, I have no idea where to start! Alternatively, if there is a simpler way of doing it, please let me know. But I don't want to have a list of 'item_1_id', 'item_2_id' etc on the meal!! Thanks!!
<%= form_for(#meal) do |f| %>
<% if #meal.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#meal.errors.count, "error") %> prohibited this meal from being saved:</h2>
<ul>
<% #meal.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :category %><br />
<%= f.text_field :category %>
</div>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :child_id %><br />
<%= f.number_field :child_id %>
</div>
<div class="field">
<%= f.label :time %><br />
<%= f.date_select :time %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

There is a great railscast episode that covers this. Also, you would want to use javascript to have a "add item" link. This example below, will always have one new item available.
You would want to do something like this
view
<%= f.fields_for :items do |builder| %>
<fieldset>
</fieldset>
<% end %>
controller
#meal.items.build
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2

Related

Nested forms rails field does not update

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 %>

Rails - Displaying Foreign Key References in a form

I'm doing a simple exercise with two models. Sport and Teams, defined as
rails g scaffold sport name:integer
rails g scaffold team name:integer fans:integer sport:references
(Note: The reason I'm using scaffold is rapidly prototyping so I can learn/experiment with the parts I'm not familiar with yet)
Problem is that my "sport" (i.e. the foreign key reference) is showing like the following
So it's got that weird #<blahl blah> notation to it...
<%= form_for(#team) do |f| %>
<% if #team.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#team.errors.count, "error") %> prohibited this team from being saved:</h2>
<ul>
<% #team.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :fans %><br />
<%= f.number_field :fans %>
</div>
<div class="field">
<%= f.label :sport %><br />
<%= f.text_field :sport %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I've tried changing the one line to #team.sport.name but it results in an error undefined method 'Ice Hockey' for #<Team:0x3e7e040>... Any ideas how to properly display name from here??
You are using a text_field for referencing an existing object, a select with Sports as options would be more appropriate here.
This is where it has to be changed:
<div class="field">
<%= f.label :sport %><br />
<%= f.text_field :sport %>
</div>
To:
<div class="field">
<%= f.label :sport %><br />
<%= f.select :sport_id, options_for_select(Sport.all.map{|s|[s.name, s.id]}) %>
</div>
The f.select will generate a select box in HTML, the options will me all the sports in your DB.
Some documentation about it:
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/select
http://guides.rubyonrails.org/form_helpers.html#select-boxes-for-dealing-with-models
A cleaner way would be to set a variable #sports in your controller and call it then in your views:
# in controller
def edit
#sports = Sport.scoped
#...
# in edit view
<div class="field">
<%= f.label :sport %><br />
<%= f.select :sport_id, options_for_select(#sports.map{ |s| [s.name, s.id] }) %>
</div>
Additionnal information: If you want to "pre-select" an option for the select, you have to pass it as the second argument of the options_for_select helper:
options_for_select(#sports.map{ |s| [s.name, s.id] }, params[:sport_id])
# this will select by default the option that matches the value of params[:sport_id]

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 %>

checkbox in form associated with Model in Ruby on rails

I have a Model "Startup" and I have a other Model "Categorie". The two tables are associated.
I'd like call the data of Categoria through to form of Startup, this categories displayed with a checkbox. Inside the form Startup Form I have the categorie_id. This is the code
<%= form_for(#startup) do |f| %>
<% if #startup.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#startup.errors.count, "error") %> prohibited this startup from being saved:</h2>
<ul>
<% #startup.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.collection_select :round_id, Round.order(:name), :id, :name, include_blank: true %>
</div>
<div class="field">
<%= f.label :category %><br />
<%= f.text_field :category_id %>
</div>
<div class="field">
<%= f.collection_select :country_id, Country.order(:name), :id, :name, include_blank: true %>
</div>
<div class="actions">
<%= f.submit %> </div> <% end %>
How to display the data of Categories within form with a checkboxs ?
Any idea.
pdt: My english is really bad.
If a Startup can have only one Category, you can do like this in your view:
<div class="field">
<%= f.label :category %><br />
<%= f.collection_select :category_id, Category.all, :id , :name %>
</div>
This will output a dropdown menu with all the categories. Make sure that the Category model has the attribute name.
As you said, a Startup belongs to one Category, so using radiobuttons (checkboxes are here for multiple relation, means you could choose multiple categories):
<div class="field">
<% Category.all.each do |category| %>
<%= f.radio_button :category_id, category.id %>
<%= f.label :category_id, category.name %>
<% end %>
</div>
You may have to add <br /> tags, and html options to make it looks better.
As MrYoshiji says, you can use:
It will display the category name on the screen, and the value sent will be the id.
You can find more details here : http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
I advise you to use the simple_form gem to generate your form. It's a very simple gem to use and customize ! look at it ;)

Ruby Rails form

Hi there I'm extremely new to Ruby and I'm currently working with two models and two corresponding databases. A Quiz which has_many questions. And I'm trying to get the questions to show up in the quiz "edit view" here's what I have.
What currently is not working is the form entry for "questions" (see commented part below). I don't think I understand the expressions preceded by the colons very well. (e.g. :title, :quiz_date etc>) are they regular variables?
Anyway, the block of code in question successfully makes a form but using :questions it puts all the information from the questions row of the database into to the form filed (i.e id, question, answer, possible answers, etc). But it doesn't give me just the value of the question field.
But if I change it to :question (hoping to just get the value of the question field in the questions table) I get an error. I also tried :questions.question and just plain questions.question. None of these worked.
Any suggestions?
<%= form_for(#quiz) do |f| %>
<% if #quiz.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#quiz.errors.count, "error") %> prohibited this quiz from being saved: </h2>
<ul>
<% #quiz.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 :quiz_date %><br />
<%= f.date_select :quiz_date %>
</div>
<div class="field">
<%= f.label :reading %><br />
<%= f.text_field :reading %>
</div>
<div>
#the problem code
<% #quiz.questions.each do |questions| %>
<div class="question">
<%= f.label :questions %><br />
<%= f.text_field %>
</div>
<% end %>
#end problem code
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You are going to need to adds accepts_nested_attributes in your Quiz model
Class Quiz < ActiveRecord::Base
accepts_nested_attributes_for :questions
Then in your form add
<%= f.fields_for :questions do |build| %>
<div class="question">
<%= build.label :questions %><br />
<%= build.text_field :questions %> #whatever attribute in your questions model
<%end%>
You will find this Railscast very helpful, http://railscasts.com/episodes/196-nested-model-form-part-1

Resources