NoMethodError during Lynda Rails 3 tutorial - ruby-on-rails

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

Related

how to List date in order of number of another data?

class Subject < ActiveRecord::Base
attr_accessible :name, :teacher_id
has_and_belongs_to_many :courses
belongs_to :teacher
has_many :users, :through =>:feedback
has_many :feedbacks
end
class Course < ActiveRecord::Base
attr_accessible :name
has_many :users
has_and_belongs_to_many :subjects
validates :name, presence: true, length: { maximum: 50 }
end
class Feedback < ActiveRecord::Base
attr_accessible :rating, :recommendations, :strengths, :subject_id, :user_id, :weaknesses
belongs_to :user
belongs_to :subject
end
class User < ActiveRecord::Base
attr_accessible :course_id, :email, :gender, :name, :password, :password_confirmation
has_secure_password
belongs_to :course
has_many :feedbacks
has_many :subjects, :through =>:feedback
end
There is a join table between course and subjuct
I am a student and freshman in rails,I have some problem in this final project
How to
List subjects in order of number of feedbacks.
List students with no feedbacks.
I have no idea how to do it. Thanks very much
I am providing solution for two queries you need:
List subjects in order of number of feedbacks
#subjects = Subject.find(:all, :include=>:feedbacks).sort_by { |p| p.feedbacks.size}
List students with no feedbacks
User.find(:all, :include => :feedbacks, :conditions => "feedbacks.id is null")

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

setting up databases for associations on Ruby on Rails

First time working on ruby on rails and I have an app with the following 3 models:
class User < ActiveRecord::Base
attr_accessible :username, :name, :email, :password
has_many :comments
has_many :ideas, :inverse_of => :user
end
class Idea < ActiveRecord::Base
attr_accessible :title, :description, :rank, :user_id, :status, :privacy, :created_on, :updated_on
belongs_to :user, :inverse_of => :ideas
has_many :comments
end
class Comment < ActiveRecord::Base
attr_accessible :text, :rank, :user_id, :idea_id, :created_on
belongs_to :user
belongs_to :idea
end
I have a table for Comments created like:
create_table :comments do |t|
t.string :comment_id
t.string :text
t.string :rank
t.timestamps
end
I am trying to seed for these. What I'm trying to understand is how a single comment with a parent idea and a parent user is stored in the database, since the columns can only hold one parent at a time. Should I create a separate table that holds comment_id, user_id and idea_type, where a single comment gets entered in twice for each parent?
Thanks!
It sounds like you are trying to implement Comment as a join model which indicates that a particular User's comment on an Idea. If so, you should be able to accomplish that as follows:
class User < ActiveRecord::Base
attr_accessible :username, :name, :email, :password
has_many :comments
has_many :commented_ideas, :class_name => 'Idea', :through => :comments, :source => :comment
end
class Idea < ActiveRecord::Base
attr_accessible :title, :description, :rank, :user_id, :status, :privacy, :created_on, :updated_on
belongs_to :user # the user who created the Idea
has_many :comments
has_many :commented_users, :class_name => 'User', :through => :comments, :source => :user
end
class Comment < ActiveRecord::Base
attr_accessible :text, :rank, :user_id, :idea_id, :created_on
belongs_to :user
belongs_to :idea
end
create_table :comments do |t|
t.string :text
t.string :rank
t.integer :user_id
t.integer :idea_id
t.timestamps
end

How do I validate the uniqueness of a has_many :through join model?

I have users and issues joined by a votership model. Users can vote on issues. They can either vote up or down (which is recorded in the votership model). First, I want to be able to prevent users from casting multiple votes in one direction. Second, I want to allow users to cast the opposite vote. So, if they voted up, they should still be able to vote down which will replace the up vote. Users should never be able to vote on an issue twice. Here are my files:
class Issue < ActiveRecord::Base
has_many :associations, :dependent => :destroy
has_many :users, :through => :associations
has_many :voterships, :dependent => :destroy
has_many :users, :through => :voterships
belongs_to :app
STATUS = ['Open', 'Closed']
validates :subject, :presence => true,
:length => { :maximum => 50 }
validates :description, :presence => true,
:length => { :maximum => 200 }
validates :type, :presence => true
validates :status, :presence => true
def cast_vote_up!(user_id, direction)
voterships.create!(:issue_id => self.id, :user_id => user_id,
:direction => direction)
end
end
class Votership < ActiveRecord::Base
belongs_to :user
belongs_to :issue
end
class VotershipsController < ApplicationController
def create
session[:return_to] = request.referrer
#issue = Issue.find(params[:votership][:issue_id])
#issue.cast_vote_up!(current_user.id, "up")
redirect_to session[:return_to]
end
end
class User < ActiveRecord::Base
authenticates_with_sorcery!
attr_accessible :email, :password, :password_confirmation
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
has_many :associations, :dependent => :destroy
has_many :issues, :through => :associations
has_many :voterships, :dependent => :destroy
has_many :issues, :through => :voterships
end
You would put the uniqueness constraint on the Votership model. You don't need to put validations on the association itself.
class Votership < ActiveRecord::Base
belongs_to :user
belongs_to :issue
validates :issue_id, :uniqueness => {:scope=>:user_id}
end
This means a user can only have a single vote on a given issue (up or down).
Relationship models:
class Person
has_many :accounts
has_many :computers, through: :accounts
end
class Account
belongs_to :person
belongs_to :computer
scope :administrators, -> { where(role: 'administrator') }
end
class Computer
has_many :accounts
has_many :people, through: :accounts
end
This is how it is called
person.accounts.administrators.map(&:computer)
We can do this better using ActiveRecord::SpawnMethods#merge!
person.computers.merge(Account.administrators)
Ref: https://coderwall.com/p/9xk6ra/rails-filter-using-join-model-on-has_many-through

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