cannot save data using a nested form with the cocoon gem

89 Views Asked by At

I am having trouble saving data using a nested form with the cocoon gem, and haven't been able to find a solution on SO.

I have two models: Requests has_many Votes.

I would like to create a single form that saves a new request, and a new vote simultaneously. The issue is that currently neither a new request nor a new vote is saved using the below code. I've pasted the terminal output below for completeness.

Terminal output:

Started POST "/requests" for ::1 at 2015-06-25 15:41:17 +0100
Processing by RequestsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"FCHcO1RLg2zr6mo8MpmVNMEasvPrAqyHAY5d2SdrlDUn83ppnsRhQUU33YiOZ84c4z1xMYQI4gzjLymN1NL3fw==", "request"=>{"firstname"=>"sdf", "lastname"=>"sf", "email"=>"[email protected]", "request"=>"lskdj", "description"=>"sldkjf", "votes_attributes"=>{"1435243272926"=>{"comment"=>"sadflkj", "email"=>"[email protected]", "beta"=>"1", "_destroy"=>""}}}, "commit"=>"Save"}
   (0.2ms)  begin transaction
  Vote Exists (0.2ms)  SELECT  1 AS one FROM "votes" WHERE LOWER("votes"."email") = LOWER('[email protected]') LIMIT 1
  Request Exists (0.1ms)  SELECT  1 AS one FROM "requests" WHERE LOWER("requests"."email") = LOWER('[email protected]') LIMIT 1
   (0.1ms)  rollback transaction
  Rendered requests/_vote_fields.html.haml (0.9ms)
  Rendered requests/_vote_fields.html.haml (1.0ms)
  Rendered requests/_form.html.haml (8.4ms)
  Rendered requests/new.html.erb within layouts/application (9.2ms)
 Completed 200 OK in 118ms (Views: 105.8ms | ActiveRecord: 0.5ms)

Models:

class Request < ActiveRecord::Base
  has_many :votes, dependent: :destroy
  accepts_nested_attributes_for :votes
end

class Vote < ActiveRecord::Base
  belongs_to :request
end

Requests controller

class RequestsController < ApplicationController
before_action :set_request, only: [:show, :edit, :update, :destroy]

def create
  @request = Request.new(request_params)
   if @request.save
     redirect_to @request
   else
     render 'new'
   end
end

private
 def set_request
   @request = Request.find(params[:id])
 end

 def request_params
   params.require(:request).permit(
            :id, :firstname, :lastname, :email, :request, :description, :votes, :tag_list,
            votes_attributes: [:firstname, :lastname, :email, :comment, :beta, :id, :_destroy] )
 end

end

requests/_form.html

= form_for(@request) do |f|
  .field= f.text_field :firstname, placeholder: "Requester firstname"
  .field= f.text_field :lastname, placeholder: "Requester Lastname"
  .field= f.text_field :email, placeholder: "Email"
  .field= f.text_field :request, placeholder: "Request"
  .field= f.text_field :description, placeholder: "Description"

  #votes
    = f.fields_for :votes do |vote|
      = render 'votes/vote_fields', :f => vote
    .links
      = link_to_add_association 'add vote', f, :votes, :render_options => { :wrapper => 'inline' }, partial: 'votes/vote_fields'

  .action= f.submit "Save"

requests/_votes_fields.html.haml

.nested-fields
  .form-inline
    = f.text_field :comment, :placeholder => 'comment'
    = f.text_field :email, :placeholder => 'email'
    = f.check_box :beta, :placeholder => 'beta', :as => :boolean
    .links
      = link_to_remove_association "remove vote", f

votes and model validations:

vote.rb
 belongs_to :request
 before_save { self.email = email.downcase } #to ensure email uniqueness
 validates :email, presence: true, length: { maximum: 250 }, uniqueness: { case_sensitive: false }
 validates :request_id, presence: :true

request.rb
 belongs_to :user
 has_many :votes, dependent: :destroy
 accepts_nested_attributes_for :votes
 before_save { self.email = email.downcase }
 validates :request, presence: true
 validates :firstname, presence: true, length: { maximum: 50 }
 validates :lastname, presence: true, length: { maximum: 50 }
 validates :email, presence: true, length: { maximum: 250 }, uniqueness: { case_sensitive: false }
 acts_as_taggable
0

There are 0 best solutions below