Error when submitting form: Nested attributes unpermitted parameters - ruby-on-rails

I've tried the solutions on this other stack overflow question but they aren't working.
I'm getting this error when submitting my form: Unpermitted parameter: organization_required_fields
Any help would be appreciated.
I have the following models:
class Organization < ActiveRecord::Base
belongs_to :user
has_many :organization_required_fields
has_many :fields, through: :organization_required_fields
accepts_nested_attributes_for :organization_required_fields, allow_destroy: true
end
class OrganizationRequiredField < ActiveRecord::Base
belongs_to :organization
belongs_to :field
end
class Field < ActiveRecord::Base
has_many :organization_required_fields
has_many :organizations, through: :organization_required_fields
end
My controller:
def update
...
#organization.update(organization_params)
...
end
private
def set_organization
#organization = Organization.find_by_id(params[:id])
...
end
def organization_params
params.require(:organization).permit(:name, :user_id, organization_required_fields_attributes: [:id, :organization_id, :field_id, :_destroy])
end
My form view
...
= f.select :organization_required_fields, options_for_select(#fields.collect {|rf| [ rf.name.titleize, rf.id ] }, #organization.fields.collect{ |orf| orf.id }),{ :prompt => "Please select"},{ :multiple => true, :size => 15 }
...

I actually changed a lot by following this rails cast
I also had to change the organization_params to
params.require(:organization).permit(:name, :user_id, { field_ids: []})

You need to use fields_for in your form.

Related

Belongs_to relationship in edit

I'm encountering a problem when editing a form with a belongs_to relationship (extra_guest belongs_to age_table).
I am able to create a new extra_guest and assign it to an age_table, but I cannot get the edit/update to work as my update function returns a falseClass.--> #extra_guest.update(extra_guest_params).errors.full_messages returns undefined method `errors' for false:FalseClass
Code
models
class ExtraGuest < ApplicationRecord
belongs_to :age_table
validates :age_table, presence: true
end
class AgeTable < ApplicationRecord
belongs_to :park
has_many :extra_guests, dependent: :destroy
validates :name, :age_from, :age_to, presence: true
validates_associated :extra_guests
end
class Attraction < ApplicationRecord
belongs_to :park
has_many :extra_guests, dependent: :destroy
accepts_nested_attributes_for :extra_guests, allow_destroy: true
validates :name, presence: true
end
class Park < ApplicationRecord
has_many :attractions, dependent: :destroy
has_many :age_tables, dependent: :destroy
validates :name, :currency, presence: true
end
extra_guests_controller
def edit
#extra_guest = ExtraGuest.find(params[:id])
#age_table = #extra_guest.age_table
#age_table_list = AgeTable.where(park: #attraction.park)
end
def update
#extra_guest = #attraction.extra_guests.find(params[:id])
#age_table = AgeTable.find(params[:age_table])
authorize #extra_guest
if #extra_guest = #extra_guest.update(extra_guest_params)
redirect_to root_path
else
#attraction = Attraction.find(params[:attraction_id])
#extra_guest = ExtraGuest.find(params[:id])
#age_table_list = #attraction.park.age_tables
render 'edit'
end
end
private
def extra_guest_params
params.require(:extra_guest).permit(:name, :age_table_id,
extra_guest_prices_attributes: [:id, :name, :price_type, :start_date, :end_date, :price, :duration, :duration_min, :duration_max, :backend_only, :weekend_extra, :_destroy])
end
views/extra_guests/form
<%= simple_form_for [#attraction, #extra_guest] do |f|%>
<%= f.input :age_table, :as => :select, :selected => #age_table.id, :collection => #age_table_list.map {|u| [u.name, u.id]}, :include_blank => false %>
<% f.button :submit %>
Error message + params
Couldn't find AgeTable without an ID
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"l8HMnVIRybZg==",
"extra_guest"=>
{"age_table"=>"104",
"extra_guest_prices_attributes"=>
{"0"=>{"price"=>"1.0", "weekend_extra"=>"", "start_date"=>"2019-10-15", "end_date"=>"20-09-2019", "duration"=>"", "duration_min"=>"", "duration_max"=>"", "_destroy"=>"false", "id"=>"42"},
"1"=>{"price"=>"1.0", "weekend_extra"=>"", "start_date"=>"2019-10-15", "end_date"=>"2019-10-16", "duration"=>"", "duration_min"=>"", "duration_max"=>"", "_destroy"=>"false", "id"=>"43"}}},
"commit"=>"Save new option",
"attraction_id"=>"185",
"id"=>"55"}
Method update returns true or false. You can find docs here. To check errors you need to call method errors on #extra_guest object.
#extra_guest.update(extra_guest_params)
#extra_guest.errors.full_messages

Rails 5 Active Model Serializer display has many conditions in JSON

In my project I have those models and relationships:
class Course < ApplicationRecord
has_many :segments, inverse_of: :course, :dependent => :destroy, :autosave => true
accepts_nested_attributes_for :segments, :allow_destroy => true
end
class Segment < ApplicationRecord
validates :data ,presence: true, if: :segment_is_video?
validates :segment_type ,presence: true
validates_presence_of :course
belongs_to :course, inverse_of: :segments
has_many :questions
accepts_nested_attributes_for :questions, :allow_destroy => true
def segment_is_video?
segment_type == 'Video'
end
end
class Question < ApplicationRecord
validates_presence_of :segment
belongs_to :segment, inverse_of: :questions
end
I want to display the data field only if the type is Video, and I want to display questions array only if type field is Quiz. I'm using Active Model Serializer for that but it's not working. the data still displaying when the type is Quiz and the question array doesn't show at all.
this is my code for the serializers:
class CourseSerializer < ActiveModel::Serializer
attributes :id, :title, :author
has_many :segments
def root
'Course'
end
end
class SegmentSerializer < ActiveModel::Serializer
attributes :id, :unit_id, :unit_title, :name, :segment_type, :data
belongs_to :course
has_many :questions, if: -> { isQuiz }
def root
'Segments'
end
def include_data?
object.segment_type == 'Video'
end
def isQuiz
object.segment_type == 'Quiz'
end
end
class QuestionSerializer < ActiveModel::Serializer
attributes :id, :question, :answer1, :answer2, :answer3, :answer4, :correct
belongs_to :segment
def root
'Question'
end
end

Rails 4 strong parameters does not work for a polymorphic association

I have set a polymorphic association and added a nested form in the view. Im trying to create the main record and the association at the same time. The main record gets created but the association won't.
Here are the two models in question :
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
class Vehicle < ActiveRecord::Base
belongs_to :purchase_details, polymorphic: true
belongs_to :brand
belongs_to :model
belongs_to :color
belongs_to :customer
Here's the form definitions :
<%= form_for(#un_registered, url: panel_un_registereds_path, remote: true) do |f| %>
<%= f.fields_for :vehicle do |f_vehicle| %>
Here's a sample params set I get :
{"utf8"=>"✓", "un_registered"=>{"vehicle"=>{"brand_id"=>"", "model_id"=>"", "year"=>"", "engine_number"=>"gdfg", "chassis_number"=>"", "color"=>"", "options"=>""}, "original_price"=>"", "insurance"=>"", "freight"=>"", "tt"=>"", "tt_date"=>"", "duty"=>"", "clearance_fee"=>"", "other_expenses"=>"", "dealer_id"=>"", "landing_date"=>"", "loading_date"=>""}, "controller"=>"panel/un_registereds", "action"=>"create"}
Here's the controller actions :
def create
#un_registered = UnRegistered.create(un_registered_params)
end
def un_registered_params
params.require(:un_registered).permit(:original_price, :insurance, :freight, :tt, :tt_date, :duty, :clearance_fee, :other_expenses, :loading_date, :landing_date, :dealer_id, vehicle_attributes: [:id, :brand_id, :model_id, :engine_number, :chassis_number, :color_id, :year, :options, :selling_price, :customer_id, :purchase_date, :_destroy])
end
Full form code :
https://gist.github.com/THPubs/9665e0e5594e15fcc76a
New method :
def new
#un_registered = UnRegistered.new
end
Your form is fine. You just need to add below changes.
In your un_registered.rb model
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
accepts_nested_attributes_for :vehicle #this one
end
And in your controller,
def new
#un_registered = UnRegistered.new
#un_registered.build_vehicle #this one
end

Rails POSTing JSON for accepts_nested_attributes

I am playing around with Rails and Angular and trying to get a simple association to update via a JSON PUT request from the frontend.
Association: Article has_many :categories, through: :article_categories
Article model:
class Article < ActiveRecord::Base
validates :title, presence: true, uniqueness: true
validates :body, presence: true
has_many :article_categories
has_many :categories, through: :article_categories
accepts_nested_attributes_for :categories
end
I've got no issues updating the title and body, but I cannot update the article's categories.
Here are the relevant controller parts
def update
#article = Article.find(params[:id])
if #article.update(article_params)
render json: #article, status: 200
end
end
private
def article_params
params.require(:article).permit(:title, :body,
categories_attributes: [:name, :id])
end
My incoming JSON looks like this, spaced out to make it more readable:
Started PUT "/api/v1/articles/6" for 127.0.0.1 at 2014-06-01 17:53:04 +0900
Processing by Api::V1::ArticlesController#update as HTML
Parameters: {"title"=>"new title", "body"=>"blablabla", "id"=>"6", "categories"=>
[{"name"=>"Ruby", "id"=>1}, {"name"=>"Javascript", "id"=>2}, {"name"=>"HTML", "id"=>3},
{"name"=>"CSS", "id"=>4}],
"categories_attributes"=>[{"name"=>"Ruby", "id"=>1},
{"name"=>"Javascript", "id"=>2}, {"name"=>"HTML", "id"=>3}, {"name"=>"CSS", "id"=>4}],
"article"=>{"id"=>"6", "title"=>"new title", "body"=>"blablabla"}}
The only feedback I get is that article id isn't a whitelisted param. Isn't the categories_attributes what Rails looks for when it takes nested attributes? Why isn't it complaining about the categories params not being whitelisted?
We've had this problem before - you're basically bypassing the join model, which is preventing your application from working correctly.
Nested Association
Basically, you need to pass your associated data to your article_categories model before passing the categories data:
#app/models/article.rb
Class Article < ActiveRecord::Base
...
accepts_nested_attributes_for :article_categories
end
#app/models/article_category.rb
Class ArticleCategory < ActiveRecord::Base
belongs_to :category
belongs_to :article
accepts_nested_attributes_for :category
end
#app/controllers/articles_controller.rb
def new
#article = Article.new
#article.article_categories.build.build_category
end
def create
#article = Article.new(article_params)
#article.save
end
private
def article_params
params.require(:article).permit(:article, :attributes, article_categories_attributes: [categories_attributes: [:category, :options]] )
end
#app/view/articles/new.html.erb
<%= form_for #article do |f| %>
<%= f.fiels_for :article_categories do |ac| %>
<%= ac.fields_For :categories do |c| %>
<%= c.text_field :your_field &>
<% end %>
<% end %>
<% end %>
There were a couple issues here:
My json format was incorrect. The categories were not nested in article and that's why rails wasn't throwing validation errors. I changed the angular frontend to post this:
{"article"=>{"title"=>"sdfsd", "body"=>"sdf", "category_ids"=>[1, 2, 3]}}
My angular $scope contained both the category ID and name, so I had to write a function to parse out the IDs and dump them in an array. Annoying.
Next, creating an article with this JSON format was failing because of the validations on ArticleCategory. I added the inverse_of to my models as described here https://github.com/rails/rails/issues/5178 and then the validations would pass when creating a new article with categories and bypassing the join model. If I understand things correctly, this is an alternative solution to Richard Peck's answer.
The final models looked like this:
class Article < ActiveRecord::Base
validates :title, presence: true, uniqueness: true
validates :body, presence: true
has_many :article_categories, inverse_of: :article
has_many :categories, through: :article_categories
end
class Category < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
has_many :article_categories, inverse_of: :category
has_many :articles, through: :article_categories
end
class ArticleCategory < ActiveRecord::Base
belongs_to :article, inverse_of: :article_categories
belongs_to :category, inverse_of: :article_categories
validates :category, :article, presence: true
end

Nested attributes saving error

I have models
class Survey < ActiveRecord::Base
has_many :questions
acts_as_list
validates :title, :presence =>true
validates :short_description, :presence=>true
validates :description, :presence=>true
end
class Question < ActiveRecord::Base
belongs_to :survey
has_many :options
accepts_nested_attributes_for :options, :reject_if => lambda { |a| a[:title].blank? }, :allow_destroy => true
acts_as_list :scope=>:survey
end
class Option < ActiveRecord::Base
attr_accessible :title, :description, :position
belongs_to :question
acts_as_list :scope=>:survey
end
when i save or update question model it generate an error
#question = Question.new(params[:question])
#question.save
#question = Question.find(params[:id])
#question.update_attributes(params[:question])
In both cases it generates an error
NoMethodError (undefined method `survey_id' for #<Option:0xb332394>):
app/controllers/admin/questions_controller.rb:47:in `block in create'
app/controllers/admin/questions_controller.rb:46:in `create'
I can not understand why it is generating this error, since Option do not have any relation to Survey
Could it be this (on Option):
class Option < ActiveRecord::Base
attr_accessible :title, :description, :position
belongs_to :question
acts_as_list :scope=>:survey # <-- no survey_id ??
end

Resources