Insert value of select_box into table attribute - ruby-on-rails

I've got two tables:
Topics
-name
and
Queries
-topic_id
A query can have a topic and so I'm trying to create a select_box in my queries_form which inserts a selected topic into my topic_id attribute of my queries table.
What I already made is a functional select_box, but I'm unable to insert the selected item into the topic_id attribute...
<% form_for #query do |f| %>
....
<%= f.select :topic_id, :value => 'queries', Topic::find(:all).collect( &:name ) %>
<% f.submit "save" %>
<% end %>
Thanks a lot for helping me

First set your relationships in your model like this :
class Topic < ActiveRecord::Base
has_many :queries
end
and
class Query < ActiveRecord::Base
belongs_to :topic
end
Then you can write in your form view this:
<% form_for #query do |f| %>
....
<%= f.select :topic_id, Topic.all.collect {|topic| [topic.name, topic.id]} %>
<% f.submit "save" %>
<% end %>

Related

Rails/ActiveRecord - association not saving

I can't get my CheckIn record to save because the associated Tenancy isn't saving.
I have three models with associations:
class Property < ApplicationRecord
has_many :tenancies
end
class Tenancy < ApplicationRecord
belongs_to :property
has_many :check_ins
end
class CheckIn < ApplicationRecord
belongs_to :tenancy
accepts_nested_attributes_for :tenancy
end
I want the CheckIn new action to create both the CheckIn and the associated Tenancy:
def new
#check_in = CheckIn.new
#check_in.build_tenancy.property_id = params[:property_id]
end
I have to include the property_id part otherwise the Tenancy won't save.
The form in check_ins/new.html.erb:
<%= form_for #check_in, url: property_check_ins_path do |f| %>
<%= f.label :date_time %>
<%= f.datetime_select :date_time, {minute_step: 15} %>
<%= f.label :tenancy %>
<%= f.fields_for :tenancy do |i| %>
<%= i.date_select :start_date %>
<% end %>
<%= f.submit "Create Check In" %>
<% end %>
I've added tenancy attributes to the strong params in the CheckInsController:
def check_in_params
params.require(:check_in).permit(:tenancy_id, :date_time, tenancy_attributes: [:start_date])
end
It's worth noting that the check_ins routes are nested in properties:
resources :properties do
resources :check_ins, only: [:new, :create]
end
So the problem is that by the time I get to the create action in the CheckInsController, the tenancy that I built has disappeared. I'm not sure how and when each of the records should be being saved and the slight complexity of what I'm trying to achieve has made it quite difficult to find relevant help so any ideas?
I'm using Rails 5.
The problem was that the property attached to the tenancy was being forgotten. I removed the property attachment from the new action:
def new
#check_in = CheckIn.new
#check_in.build_tenancy
end
Added a hidden field for property_id to the form (as well as adding :property_id to the strong params):
<%= f.fields_for :tenancy do |i| %>
<%= i.date_select :start_date %>
<%= i.hidden_field :property_id, value: params[:property_id] %>
<% end %>
And saved the tenancy in the CheckIn create action, prior to saving the check in itself:
def create
#check_in = CheckIn.new(check_in_params)
#check_in.tenancy.save
if #check_in.save
redirect_to property_check_in_path(#check_in.tenancy.property.id, #check_in)
else
render :new
end
end
I'd certainly be interested if anyone could pick holes in this solution or offer a better one.
Using nested resources (check_ins depends from properties) you create a namespaces routes. form_for helper ( rails guides - form helpers ) when you build your form, need a Property reference also.
I try to explain me better with an example:
#checks_controller.rb
def new
#property = Property.new
#check_in = #property.build_check_ins
#check_in.build_tenancy
end
#check_ins/new.html.erb
<%= form_for [#property, #check_in], url: property_check_ins_path do |f| %>
<%= f.label :date_time %>
<%= f.datetime_select :date_time, {minute_step: 15} %>
<%= f.label :tenancy %>
<%= f.fields_for :tenancy do |i| %>
<%= i.date_select :start_date %>
<% end %>
<%= f.submit "Create Check In" %>
<% end %>
I haven't tried this code, but I hope this give you at least a way to follow to solve your problem.

Rails Forms Passing Array in Params for M to M Associaton

Edit: Essentially looking to pass something like this:
{
'tabled_id' : '1',
'recipes' : [{
{ 'recipe_id' : '3',
'quantity' : '2'
}
{ 'recipe_id' : '5',
'quantity' : '1'
}
}]
}
And I think I should do params.require(:order).permit(:table_id, {recipes:, [:id,:quantity]} ) on the controller side.
I'm learning Rails building an ordering system and I'm stuck trying to build a form for Orders that passes quantity. Where Orders is a nested resource for Restaurant.
My models look like this:
class Restaurant < ActiveRecord::Base
has_many :orders
has_many :recipes, dependent: :destroy
end
class Order < ActiveRecord::Base
belongs_to :restaurant
has_many :order_recipes, dependent: :destroy
has_many :recipes, through: :order_recipes
end
class Recipe < ActiveRecord::Base
belongs_to :restaurant
has_many :order_recipes
has_many :orders, through: :order_recipes
end
View:
<%= form_for([#restaurant, #order]) do |order_form| %>
<%= order_form.label :Table_Number %>
<%= order_form.number_field :table_id %>
<h3>Recipes: </h3>
<br>
<% #restaurant.recipes.each do |recipe| %>
<%= order_form.fields_for :recipe, recipe do |r| %>
<%= r.label recipe.name %>
<%= r.hidden_field :id %>
<%= r.number_field :quantity %>
<% end %>
<% end %>
<%= order_form.submit(#order.new_record? ? "Create Order" : "Edit Order", class: "btn btn-success") %>
<% end %>
This will yield a form that looks correct, but won't pass all parameters. Let's say I have 3 recipes. And I set their quantities to 2,3,4 respectively, and the table_id to 1. When I inspect the parameters, I see that only the last recipe with its quantity has been passed. params[:order] => {"table_id"=>"1", "recipe"=>{"id"=>"4", "quantity"=>"4"}} I need to be able to send all recipes with their assigned quantities. Also, I'm using the accepted answer in this question to be able to access the quantity column: Rails 4 Accessing Join Table Attributes
When you hand in fields_for :recipes multiple times, the fields_for method is not aware of you sending an array of things. Therefore it will name the parameters as if it was only one instance, so only the last instance will come through. You have to hand in the array of recipes to the fields_for, so it can name the parameters, so that rails knows it is an array of things when it gets picked up again (docs).
This is because form parameters in browsers do not support nesting by default. The actual parameters are flat key-value paramters. Rails has some naming conventions on how paramters can be named, so they will automatically be coerced to an array.
<%= form_for([#restaurant, #order]) do |order_form| %>
<%= order_form.label :Table_Number %>
<%= order_form.number_field :table_id %>
<h3>Recipes: </h3>
<br>
<%= order_form.fields_for :recipes, #restaurant.recipes do |r| %>
<%= r.label recipe.name %>
<%= r.hidden_field :id %>
<%= r.number_field :quantity %>
<% end %>
<%= order_form.submit(#order.new_record? ? "Create Order" : "Edit Order", class: "btn btn-success") %>
<% end %>

Rails 4 - checkboxes for has_and_belongs_to_many association

I recently had a problem getting checkboxes to work for a has_and_belongs_to_many (HABTM) association in Rails 4. I was able to find the information on how to get it working correctly in a few disparate places, but thought it would be good to document the few simple steps necessary to get it working correctly in one place here on StackOverflow.
As a setup assume a model of Kennel with a HABTM association to Handler.
class Kennel
has_and_belongs_to_many :handlers
end
This is all you need to do for the form: Don't do it manually when there is a built in helper.
<%= form_for #kennel do |f| %>
<%= f.collection_check_boxes(:handler_ids, Handler.all, :id, :to_s) %>
<% end %>
The form should have something like this:
<%= form_for(#kennel) do |form| %>
...
<div class="field">
<div class="field_head">Handlers</div>
<%= hidden_field_tag("kennel[handler_ids][]", nil) %>
<% Handler.order(:name).each do |handler| %>
<label><%= check_box_tag("kennel[handler_ids][]", id, id.in?(#kennel.handlers.collect(&:id))) %> <%= handler.name %></label>
<% end %>
</div>
...
<% end %>
The hidden_field_tag allows the user to uncheck all the boxes and successfully remove all the associations.
The controller needs to allow the parameter through strong parameters in the permitted_params method:
params.permit(kennel: [:city, :state
{handler_ids: []},
:description, ...
])
References:
http://railscasts.com/episodes/17-habtm-checkboxes
https://coderwall.com/p/_1oejq
I implement has_and_belongs_to_many association this way:
model/role
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
model/user
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
users/_form.html.erb
---
----
-----
<div class="field">
<% for role in Role.all %>
<div>
<%= check_box_tag "user[role_ids][]", role.id, #user.roles.include?(role) %>
<%= role.name %>
</div>
<% end %>
</div>
users_controller.rb
def user_params
params.require(:user).permit(:name, :email, { role_ids:[] })
end
Intermediate table_name should be roles_users and there should be two fields:
role_id
user_id

Nested model form with mutliple has_many/belongs_to associations

I have three models:
class Rate < ActiveRecord::Base
attr_accessible :user_id, :car_id, :rate
belongs_to :user
belongs_to :car
end
class User < ActiveRecord::Base
attr_accessible :name
has_many :rates
accepts_nested_attributes_for :rates
end
class Car < ActiveRecord::Base
attr_accessible :name
has_many :rates
accepts_nested_attributes_for :rates
end
And one controller:
class UsersController < ResourceController
def new
# Assume user is loaded
#user.rates.build
end
end
I'm trying to build a nested form that will associate a list of users/cars and their associated rates.
Something like:
<% form_for #user do |f| %>
<%= #user.name %><br />
<% Car.all.each do |car| %>
<%= car.name %><br />
<%= f.fields_for :rates do |r| %>
<%= r.number_field :rate %>
<% end %>
<% end %>
<% end %>
The problem is that I would like the Rate model to store data as follows:
USER_ID CAR_ID RATE
1 1 10
1 2 20
1 3 30
2 1 40
3 2 50
I cannot figure out how to properly build the fields_for helper to build the proper params for both the user_id and the car_id.
Something like:
user[car=1][rate]
user[car=2][rate]
I've tried being more explicit with the fields_for like this:
<%= r.fields_for 'user[car][rate]' %>
But it still doesn't build out the nested parameters properly. The car parameter is not correctly identified.
Any help would be appreciated! Thanks.
EDIT:
The controller action has to be under user. The example above has been shortened for brevity but other user-related attributes are available through the form so it has to use the users controller.
ANSWER:
I figured out a way to do it. I've added my own answer that explains it.
<% form_for #user do |f| %>
<%= #user.name %><br />
<%= f.fields_for :rates do |r| %>
<% Car.all.each do |car| %>
<%= car.name %><br />
<%= r.number_field :rate %>
<% end %>
<% end %>
<% end %>
This may be solution of your problem. Just check it.
The form is going to create a new rate instead of a new user, so the method should be in RatesController instead of UsersController.
With this logic the problem seems solved. You can write field_for rate[user] and field_for rate[car]
I think I've got it figured out.
In my controller, I've modified the build method as follows:
Car.all.each { |c| #user.rates.build(car_id: c.id) } if #user.rates.count == 0
Then, in my model, I need the following:
attr_accessible :rates_attributes
Finally, the fields_for block should look like this (remember, this is in the #user form object f):
<%= f.fields_for :rates do |r| %>
<%= r.hidden_field :car_id %>
<%= r.object.car.name %><br />
<%= r.number_field :rate %>
<% end %>
This builds the params hash properly and create the rate model entries when the form is submitted.
The check on existing user rates in the controller will ensure that the existing values are used in the form and new ones are not built (which I thought build took into consideration... ?).

Getting specific items from iterating rails 3

I am trying to find a way to pull all notes that are assigned to a course but only when necessary. I have a show page which shows all of the notes for a quiz.
course show.html.erb
<%= #course.name %>
<% #quiz.notes.each do |note| %>
<%= link_to note.title, quiz_note_path(#quiz, note) %><br/>
<% end %>
The above code works find except it pulls all of the notes and not the notes that are assigned to that course. How can I tell rails to only pull the note if note and course name are equal?
update!
In the note new.html.erb I have am using collection_select
<%= f.collection_select(:course_ids, #quiz.courses, :id, :note_name, options = {:prompt => "Choose"}) %>
It seems like you don't have relationship between course and quiz.
A course has many quizzes, a quiz has many notes. You should setup your relationship this way, so it won't pull out unnecessary notes that are not related to the current course.
The trick here is to pull all notes inside a course by using has_many :through.
class Course < ActiveRecord::Base
has_many :quizzes
has_many :notes, :through => quizzes
end
class Quiz < ActiveRecord::Base
has_many :notes
end
class Note < ActiveRecord::Base
belongs_to :quiz
end
<%= #course.name %>
<% #course.notes.each do |note| %>
<%= link_to note.title, quiz_note_path(note.quiz, note) %><br/>
<% end %>
Try something like this.
<%= #course.name %>
<% #quiz.notes.select { |n| n.title == #course.name }.each do |note| %>
<%= link_to note.title, quiz_note_path(#quiz, note) %><br/>
<% end %>
Enumerable.select evaluates the block and returns only the elements for which it was true.

Resources