Many-to-many controller on rails 4 - ruby-on-rails

I'm trying to do a many-check-box with a many-to-many association.
I have tree models
Empresa:
class Empresa < ActiveRecord::Base
has_many :empresa_pagamento
has_many :formas_pagamentos, :through => :empresa_pagamento
has_one :tipo_restaurante
has_many :produtos
end
Forma Pagamento
class FormaPagamento < ActiveRecord::Base
has_many :empresa_pagamento
has_many :empresas, :through => :empresa_pagamento
end
Empresa Pagamento
class EmpresaPagamento < ActiveRecord::Base
belongs_to :empresa
belongs_to :forma_pagamento
end
On my empresa_controller I have my params
def empresa_params
params.require(:empresa).permit(:nome, :descricao, :cnpj, :razao_social,:formas_pagamentos, :tipo_restaurante)
end
When i try to save i do :
def create
#empresa = Empresa.new(empresa_params)
respond_to do |format|
if #empresa.save
#empresa.formas_pagamentos.each do |forma_pagamento|
empresa_pagamento = EmpresaPagamento.new
empresa_pagamento.forma_pagamento = FormaPagamento.find(forma_pagamento)
empresa_pagamento.empresa = #empresa
empresa_pagamento.save
end
format.html { redirect_to #empresa, notice: 'Empresa was successfully created.' }
format.json { render :show, status: :created, location: #empresa }
else
format.html { render :new }
format.json { render json: #empresa.errors, status: :unprocessable_entity }
end
end
end
on my _form i have
<div class="field">
<%= f.label :formas_pagamentos %><br>
<%= f.collection_select(:formas_pagamentos, FormaPagamento.all, :id, :nome,{:prompt => "Selecione"}, {:multiple => true}) %>
</div>

Related

Rails 5 - Strong Parameters for Nested Attributes on Associated Objects

I am trying to create a nested attribute form for my Request model.
My parameters are not saving correctly when the Create action is triggered. Though in my console, the data is structured correctly for how I want it to be entered.
The :quantity attribute is on the JoinTable model of RequestDrink.
How can I white-list these parameters correctly?
Console Output
Started POST "/requests" for 127.0.0.1 at 2017-06-08 12:38:40 -0400
Processing by RequestsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"3ljcH44E7ZrEXNztlgGacyA0nyumNsTX6NyMMu9N+3SY0rCRXSsj/hsg0JP8jtVfDFkcEWOWHi/VwHrgertlLg==", "request"=>{"concierge_name"=>"Alex", "concierge_number"=>"954-123-4567", "concierge_email"=>"alex#email.com", "client_name"=>"Adam", "client_number"=>"954-765-4321", "client_email"=>"adam#email.com", "hotel_employee"=>"0", "concierge_service"=>"0", "vip_promoter"=>"0", "arriving_with_client"=>"1", "client_alone"=>"0", "males"=>"", "females"=>"1", "table_minimum"=>"1000", "event_date_id"=>"1", "arrival_time(1i)"=>"2017", "arrival_time(2i)"=>"6", "arrival_time(3i)"=>"8", "arrival_time(4i)"=>"16", "arrival_time(5i)"=>"38", "drinks_attributes"=>[{"id"=>"1", "quantity"=>"1"}, {"id"=>"2", "quantity"=>""}, {"id"=>"3", "quantity"=>""}, {"id"=>"4", "quantity"=>""}], "commit"=>"Submit"}
Completed 404 Not Found in 18ms (ActiveRecord: 0.0ms)
ActiveRecord::RecordNotFound (Couldn't find Drink with ID=1 for Request with ID=):
app/controllers/requests_controller.rb:34:in `create'
app/models/request.rb
class Request < ApplicationRecord
has_many :request_drinks
has_many :drinks, through: :request_drinks
accepts_nested_attributes_for :drinks
end
app/models/drinks.rb
class Drink < ApplicationRecord
has_many :request_drinks
has_many :requests, through: :request_drinks
end
app/models/request_drink.rb
class RequestDrink < ApplicationRecord
belongs_to :request
belongs_to :drink
end
app/controllers/request_controller.rb
class RequestsController < ApplicationController
before_action :set_request, only: [:show,
:edit,
:update,
:destroy]
def index
redirect_to root_path unless admin_signed_in?
#requests = Request.search(params[:term], params[:filter], params[:page])
end
def show
end
def new
#request = Request.new
#drinks = Drink.active
#chasers = Chaser.active
#table_locations = TableLocation.active
#event_dates = EventDate.active
end
def edit
end
def create
#request = Request.new(request_params)
#request.people = (#request.males || 0) + (#request.females || 0)
#drinks = Drink.active
#chasers = Chaser.active
#table_locations = TableLocation.active
#event_dates = EventDate.active
respond_to do |format|
if #request.save
format.html { redirect_to thanks_path, notice: 'Request was successfully created.' }
format.json { render :show, status: :created, location: #request }
else
format.html { render :new }
format.json { render json: #request.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #request.update(request_params)
format.html { redirect_to #request, notice: 'Request was successfully updated.' }
format.json { render :show, status: :ok, location: #request }
else
format.html { render :edit }
format.json { render json: #request.errors, status: :unprocessable_entity }
end
end
end
def destroy
#request.destroy
respond_to do |format|
format.html { redirect_to requests_url, notice: 'Request was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_request
#request = Request.find(params[:id])
end
def request_params
params.require(:request).permit(:concierge_name,
:concierge_number,
:concierge_email,
:client_name,
:client_number,
:client_email,
:hotel_employee,
:concierge_service,
:vip_promoter,
:arriving_with_client,
:client_alone,
:people,
:males,
:females,
:table_minimum,
:arrival_time,
:comments,
:event_date_id,
:drinks_attributes => [:id, :quantity]
)
end
end
app/views/requests/_form.html.erb
<%= form_with(model: request, local: true) do |f| %>
...
<h4>Drinks</h4>
<% #drinks.all.each do |d| %>
<%= hidden_field_tag "request[drinks_attributes][][id]", d.id %>
<%= number_field_tag "request[drinks_attributes][][quantity]", 0, in: 0..10 %>
<%= d.name %>
<br />
<% end %>
...
<% end %>
The :quantity attribute is on the JoinTable model of RequestDrink.
Yet your are using drinks instead of request_drinks. Try changing your code to use the latter:
Model:
class Request < ApplicationRecord
has_many :request_drinks
has_many :drinks, through: :request_drinks
accepts_nested_attributes_for :request_drinks
end
View:
...
<%= hidden_field_tag "request[request_drinks_attributes][][id]", d.id %>
<%= number_field_tag "request[request_drinks_attributes][][quantity]", 0, in: 0..10 %>
...
Controller:
class RequestsController < ApplicationController
# other actions
def request_params
params.require(:request).permit(..., :request_drinks_attributes => [:id, :quantity])
end
end
Thank you, this worked as well as tweaking my parameters a little more. This is the completed code
app/models/request.rb
class Request < ApplicationRecord
has_many :request_drinks
has_many :drinks, through: :requests
accepts_nested_attributes_for :request_drinks
end
app/controllers/request_controller.rb
class RequestController < ApplicationRecord
...
def request_params
params.require(:request).permit(:concierge_name,
:concierge_number,
:concierge_email,
:client_name,
:client_number,
:client_email,
:hotel_employee,
:concierge_service,
:vip_promoter,
:arriving_with_client,
:client_alone,
:people,
:males,
:females,
:table_minimum,
:arrival_time,
:comments,
:is_deleted,
:approved,
:attended,
:event_date_id,
:request_drinks_attributes => [:request_id, :drink_id, :quantity]
:table_location_ids => []
)
end
end
app/views/requests/_form.html.erb
...
<h4>Drinks</h4>
<% #drinks.all.each do |d| %>
<%= hidden_field_tag "request[request_drinks_attributes][][request_id]", request.id %>
<%= hidden_field_tag "request[request_drinks_attributes][][drink_id]", d.id %>
<%= number_field_tag "request[request_drinks_attributes][][quantity]", 0, in: 0..10 %>
<%= d.name %>
<br />
<% end %>

Ruby on rails - adding multiple choice checkboxes - ERROR - undefined method `check_box_tag'

I'm tying do add a new kind of answers to my polls app. It will be a multiple choice with checkboxes. The user can choose one or more possible answers from the checkboxes presented.
I'm struggling to make it work, I'm getting the error:
NoMethodError in Replies#new
undefined method `check_box_tag' for #<ActionView::Helpers::FormBuilder:0x007fae8bd82f48>
right i have this models:
answer.rb
class Answer < ActiveRecord::Base
belongs_to :reply
belongs_to :question
belongs_to :possible_answer
end
poll.rb
class Poll < ActiveRecord::Base
validates_presence_of :title
has_many :questions
has_many :replies
end
possible_answer.rb
class PossibleAnswer < ActiveRecord::Base
belongs_to :question
end
question.rb
class Question < ActiveRecord::Base
belongs_to :poll
has_many :possible_answers
has_many :answers
accepts_nested_attributes_for :possible_answers, reject_if: proc { |attributes| attributes['title'].blank? }
end
reply.rb
class Reply < ActiveRecord::Base
belongs_to :poll
has_many :answers
accepts_nested_attributes_for :answers
end
In the views I have a reply/new.html.erb that already work for radio and open answer questions, by rendering the partial by kind:
<h1><%= #poll.title %></h1>
<%= form_for [ #poll, #reply ] do |f| %>
<%= f.fields_for :answers do |c| %>
<%= render c.object.question.kind, c: c %>
<% end %>
<p>
<%=f.submit 'Finish poll', class: 'btn btn-primary'%>
</p>
<% end %>
and the partial for the checkbox:
<p>
<%= c.label :value, c.object.question.title %>
</p>
<div class="checkbox">
<% c.object.question.possible_answers.each do |possible_answer| %>
<p>
<label>
<%= c.check_box_tag :possible_answer_id, possible_answer.id %>
<%= possible_answer.title %>
<%= c.hidden_field :question_id %>
</label>
</p>
<% end %>
</div>
replies_controller.rb
class RepliesController < ApplicationController
def new
#poll = Poll.find params[:poll_id]
#reply = #poll.replies.build
#poll.questions.each { |question| #reply.answers.build question: question }
end
def create
#poll = Poll.find params[:poll_id]
#reply = #poll.replies.build reply_params
if #reply.save
redirect_to #poll, notice: 'Thank you for the taking the poll.'
else
render :new
end
end
private
def reply_params
params.require(:reply).permit(:poll_id, {
answers_attributes: [:value, :question_id, :reply_id, :possible_answer_id] })
end
end
questions_controller
class QuestionsController < ApplicationController
before_action :set_question, only: [:show, :edit, :update, :destroy]
before_action :set_poll
before_action :set_kind_questions
def index
#questions = Question.all
end
def show
end
def new
##question = Question.new
#question = #poll.questions.build
5.times { #question.possible_answers.build }
end
def edit
end
def create
##question = Question.new(question_params)
#question = #poll.questions.build(question_params)
respond_to do |format|
if #question.save
format.html { redirect_to #poll, notice: 'Question was successfully created.' }
format.json { render :show, status: :created, location: #question }
else
format.html { render :new }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #question.update(question_params)
format.html { redirect_to #question, notice: 'Question was successfully updated.' }
format.json { render :show, status: :ok, location: #question }
else
format.html { render :edit }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
def destroy
#question.destroy
respond_to do |format|
format.html { redirect_to #question, notice: 'Question was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_question
#question = Question.find(params[:id])
end
def question_params
params.require(:question).permit(:title, :kind, :poll_id, { possible_answers_attributes: [:title, :question_id] })
end
def set_kind_questions
#kind_options = [
['Open Answer','open'],
['Multiple Radio Choice', 'radio'],
['Multiple Checkbox Choice','checkbox']
]
end
def set_poll
#poll = Poll.find params[:poll_id]
end
end
Answers migration table
class CreateAnswers < ActiveRecord::Migration
def change
create_table :answers do |t|
t.references :reply, index: true, foreign_key: true
t.references :question, index: true, foreign_key: true
t.references :possible_answer, index: true, foreign_key: true
t.string :value
t.timestamps null: false
end
end
end
Probably I have to use has_and_belongs_to_many association in the answers model but I'm not getting how. Can someone help me?
Thanks!
Please try to just use check_box_tag as below:
<%= check_box_tag( 'possible_answer_ids['+ possible_answer.id.to_s+']', possible_answer.id) %>

Polymorphic Associations not saving values

My models:
class LineItem < ActiveRecord::Base
attr_accessible :itemable
belongs_to :itemable, polymorphic: true
belongs_to :lead
belongs_to :cart
end
class House < ActiveRecord::Base
has_many :line_items, :as => :itemable
end
class Appartment < ActiveRecord::Base
has_many :line_items, :as => :itemable
end
line_item_controller:
def create
#line_item = #cart.line_items.build item: #object
respond_to do |format|
if #line_item.save
format.html { redirect_to #line_item.cart,
notice: 'Vakantiehuis toegevoegd in lijst.' }
format.json { render action: 'show',
status: :created, location: #line_item }
else
format.html { render action: 'new' }
format.json { render json: #line_item.errors,
status: :unprocessable_entity }
end
end
end
private
def create_object
id = params[:house_id] || params[:appartment_id]
model = "House" if params[:house_id]
model = "Apartment" if params[:apartment_id]
model = model.constantize
#object = model.find(id)
end
When a new item list is created the values in de table line_items (itemable_id, itemable_type) are not saved. What am i doing wrong here? thanks..remco
try replace:
#cart.line_items.build item: #object
to:
#cart.line_items.build itemable: #object

couldn't find Subject without an ID in #subject = Subject.find(params[:subject_id])

I have a mistake: couldn't find Subject without an ID in #subject = Subject.find(params[:subject_id])
I create many-to-many association. There are three models - teacher, subject and subscription. Subscription model includes following fields: teacher_id and subject_id.
class Subject < ActiveRecord::Base
has_many :subscriptions
has_many :teacher, :through => :subscriptions
end
class Teacher < ActiveRecord::Base
has_many :subscriptions
has_many :subjects, :through => :subscriptions
end
class Subscription < ActiveRecord::Base
belongs_to :subject
belongs_to :teacher
end
teacher_controller
def create
#subject = Subject.find(params[:subject_id])
#teacher = Teacher.new(teacher_params)
respond_to do |format|
#teacher.subjects << #subject
if #teacher.save
format.html { redirect_to #teacher, notice: 'Teacher was successfully created.'
format.json { render action: 'show', status: :created, location: #teacher }
else
format.html { render action: 'new' }
format.json { render json: #teacher.errors, status: :unprocessable_entity }
end
end
end
_form.html.erb
<%= form_for(#teacher,:html => { class: 'login-form' }) do |f| %>
<%= f.fields_for :subject do |n| %>
<%= n.select(#subject, #subjects.map{|p| [p.name, p.id]}) %>
<% end %>
...
<% form %>
resources :teachers do
resources :subjects
end
Do this instead
def create
#subject = Subject.where("id =?", params[:subject_id]).first
unless #subject.blank?
#teacher = Teacher.new(teacher_params)
......
......
else
# set flash message and redirect
end
end
In the view, _form.html.erb, replace the select_tag
<%= select_tag "subject_id", options_from_collection_for_select(#subjects, "id", "name") %>
And in the controller code,
def create
#subject = Subject.where(id: params[:subject_id]).first
if #subject.present?
#YOUR CODE GOES HERE.
else
render 'new' # OR render to the action where your teacher form resides
end
end

ActiveRecord::AssociationTypeMismatch on many to many relaitonship

Hello I am trying to build a multi select to populate a many-to-many join table. I am able to crate the new newform but am getting "AssociationTypeMismatch" when I try to save my record.
The solutions that I am finding on the web are not solving my problem.
Hoping someone can resolve what I should be doing to get rid of "AssociationTypeMismatch"
class Presenter < ActiveRecord::Base
belongs_to :seminar
belongs_to :person
end
class Seminar < ActiveRecord::Base
attr_accessible :description, :title,
has_many :presenters, :foreign_key => "person_id"
has_many :lecturer, :through => :presenters, :source => :person
accepts_nested_attributes_for :lecturer, :presenters
end
class Person < ActiveRecord::Base
attr_accessible :first_name, :last_name
has_many :presentors
has_many :lecturingAt, :through => :presentors
def fullName
first_name + " " + last_name
end
end
seminars_controller.rb
def new
#seminar = Seminar.new
#current_presenters = Person.find(:all)
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #seminar }
end
end
....
def create
#seminar = Seminar.new(params[:seminar])
respond_to do |format|
if #seminar.save
format.html { redirect_to(#seminar, :notice => 'Seminar was successfully created.') }
format.xml { render :xml => #seminar, :status => :created, :location => #seminar }
else
format.html { render :action => "new" }
format.xml { render :xml => #seminar.errors, :status => :unprocessable_entity }
end
end
end
Seminars/_form.html.erb. has which populates my collection select with the names and persion ids of
possible lecurers.
....
<div class="field">
<%= f.label :presenter_id %><br />
<%= collection_select(:seminar,:lecturer,#current_presenters, :id, :fullName,{}, {:multiple=>true} ) %>
....
On submitting the params passed into my controller
Parameters: {...., "seminar"=>{ "lecturer"=>["1", "2"], "title"=>"1234567890", "description"=>"ASDFGHJKL:"}, "commit"=>"Create Seminar"}
Getting error:
ActiveRecord::AssociationTypeMismatch (Instructor(#86075540) expected, got String(#73495120)):.
#seminar = Seminar.new
Try this
#seminar.lecturer_ids = params[:seminar].delete(:lecturer)
#seminar.update_attributes(params[:seminar])

Resources