Nested attributes saving error - ruby-on-rails

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

Related

Error when submitting form: Nested attributes unpermitted parameters

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.

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

NoMethodError during Lynda Rails 3 tutorial

What is wrong and how can I fix it?
I get the following error when I run me = AdminUser.find(1) then run me.section.edits
NoMethodError: undefined method `section' for #<AdminUser:0x007fa539ee0558>
from ...gems/activemodel-3.2.13/lib/active_model/attribute_methods.rb:407:in `method_missing'
from ...gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:149:in `method_missing'
My code
create_section_edits.rb
class SectionEdit < ActiveRecord::Base
attr_accessible :title, :body, :name, :position
belongs_to :editor, :class_name => "AdminUser", :foreign_key => 'admin_user_id'
belongs_to :section
end
admin_user.rb
class AdminUser < ActiveRecord::Base
attr_accessible :title, :body, :username, :first_name, :last_name
has_and_belongs_to_many :pages
has_many :section_edits
scope :named, lambda {|first,last| where(:first_name => first, :last_name => last)}
end
section.rb
class Section < ActiveRecord::Base
attr_accessible :title, :body, :name, :position
belongs_to :page
has_many :section_edits
end
section_edit.rb
class SectionEdit < ActiveRecord::Base
attr_accessible :title, :body, :name, :position
belongs_to :editor, :class_name => "AdminUser", :foreign_key => 'admin_user_id'
belongs_to :section
end
AdminUser has no relationship with sections, but with section_edits only.
So, instead of
me.section.edits
You need to use
me.section_edits
I think what you are missing is the fact that Admins can have multiple sections through section_edits.
Your association needs to look like this
class AdminUser < ActiveRecord::Base
attr_accessible :title, :body, :username, :first_name, :last_name
has_and_belongs_to_many :pages
has_many :section_edits
has_many :sections, through: :section_edits
scope :named, lambda {|first,last| where(:first_name => first, :last_name => last)}
end
Note the has_many through allows you to call me.sections

Can't mass-assign protected attributes: works_attributes, educations_attributes in rails nested model

I am trying to save the model called applicant with nesting to work and education model. When saving the model, I am getting:
Can't mass-assign protected attributes: works_attributes, educations_attributes error.
I am also getting an error for an undefined method `klass' for nil:NilClass. I am using Rails 3.2.
My model code:
applicant.rb
class Applicant < ActiveRecord::Base
attr_accessible :first_name, :last_name, :location, :email, :mob_no, :alternative_no, :linkedin, :facebook, :twitter, :message, :resume, :job_id
has_many :works, :dependent => :destroy
has_many :educations, :dependent => :destroy
accepts_nested_attributes_for :works, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
accepts_nested_attributes_for :educations, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
work.rb
class Work < ActiveRecord::Base
attr_accessible :applicant_id, :company_name, :description, :end_month, :end_year, :start_month, :start_year, :title
belongs_to :applicant
end
education.rb
class Education < ActiveRecord::Base
attr_accessible :applicant_id, :end_month, :end_year, :institution_name, :major, :start_month, :start_year, :title
belongs_to :applicant
end
Try including work and education attributes like this ..
class Applicant < ActiveRecord::Base
attr_accessible :works_attributes, educations_attributes

Has a relationship through four models?

I'm having trouble setting up this association between my models.
A User has many Accommodations, and Accommodations have one User.
Accommodations have many Notifications, and Notifications have one Accommodation.
Requests have many Notifications.
How can I make it so that I can get all of the Requests for a given User ( that is, User -> Accommodations (each) -> Notification -> Request)?
Update:
Here's my current controller file:
class PanelController < ApplicationController
before_filter :login_required
def index
#accommodations = current_user.accommodations.all
#requests = Array.new
#accommodations.each do |a|
a.notifications.each do |n|
#requests << Request.where('id' => n.request_id)
end
end
end
end
And models:
models/user.rb
class User < ActiveRecord::Base
[snip]
has_many :accommodations
has_many :notifications,
:through => :accommodations
end
models/accommodation.rb
class Accommodation < ActiveRecord::Base
validates_presence_of :title, :description, :thing, :location, :spaces, :price, :photo
attr_accessible :photo_attributes, :title, :description, :thing, :location, :spaces, :price
has_one :photo
has_many :notifications
belongs_to :user
accepts_nested_attributes_for :photo, :allow_destroy => true
end
models/notification.rb
class Notification < ActiveRecord::Base
attr_accessible :accommodation_id, :request_id
has_one :request
belongs_to :accommodation
end
models/request.rb
class Request < ActiveRecord::Base
belongs_to :notifications
attr_accessible :firstname, :lastname, :email, :phone, :datestart, :dateend, :adults, :children, :location, :status
validates_presence_of :firstname, :lastname, :email, :phone, :datestart, :dateend, :children, :adults, :location
end
Something like this should work:
#reqs = []
#user.accommodations.all.each do |a|
#reqs << a.notification.request
end
Assuming this is correct:
class User
has_many :accommodations
end
class Accommodation
belongs_to :user
has_many :notifications
end
class Notification
belongs_to :accomodation
belongs_to :request
end
class Request
has_many :notifications
end
Using has_many :through will not work for multiple models, as seen here: Ruby-on-Rails: Multiple has_many :through possible?
But you can do something like this in your user model:
class User
has_many :accommodations
has_many :notifications,
:through => :accommodations
def requests
self.notifications.all.collect{|n| n.request }
end
end

Resources