I am creating a project but whenever i trying to create grade for Class student using current_user.grade.create() or current_user.create_grade() getting an error "undefined method create for nil class"
My code is as follows.
Student.rb
class Student < User
has_one :user_grade , dependent: :destroy, foreign_key: 'user_id'
has_one :grade , through: :user_grade
end
Grade.rb
class Grade < ApplicationRecord
has_many :user_grades, dependent: :destroy
has_many :admins, through: :user_grades
has_many :teachers, through: :user_grades
has_many :students , through: :user_grades
has_many :guardians, through: :user_grades
has_many :posts, dependent: :destroy
validates_presence_of :cls
end
user_grade.rb
class UserGrade < ApplicationRecord
belongs_to :grade
belongs_to :admin, optional: true, class_name: 'Admin', foreign_key: 'user_id'
belongs_to :teacher, optional: true, class_name: 'Teacher', foreign_key: 'user_id'
belongs_to :student, optional: true, class_name: 'Student', foreign_key: 'user_id'
belongs_to :guardian, optional: true, class_name: 'Guardian', foreign_key: 'user_id'
end
Try using current_user.grade = Grade.new({}). Then calling current_user.save will save the association and save the new Grade.
Related
I am running a rake task to copy over some live data for demo purposes. Before each re-copy, I want to delete the old records. But when I try to Host.where(organization_id: target_org_id, customer_slug: target_customer_slug).destroy_all, I get the following err:
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "hosts" violates foreign key constraint "fk_rails_f66d1a8a7f" on table "event_attendees"
Models look something like this:
class Host
has_many :event_attendees, inverse_of: :host, dependent: :destroy
has_many :events, -> { distinct }, through: :event_attendees
end
class Attendee
has_many :event_attendees, inverse_of: :attendee, dependent: :destroy
has_many :events, through: :event_attendees
end
class Event
has_many :event_attendees, inverse_of: :event, dependent: :destroy
has_many :attendees, through: :event_attendees
end
class EventAttendee
belongs_to :event, inverse_of: :event_attendees
belongs_to :attendee, inverse_of: :event_attendees
belongs_to :host, inverse_of: :event_attendees
end
I thought dependent: :destroy should remove the associations?
Having the following associations between 3 models:
workout.rb
class Workout < ActiveRecord::Base
has_and_belongs_to_many :workout_sets, :join_table => :workout_sessions
belongs_to :warmup, :class_name => :WorkoutStep, :foreign_key => "workout_step_id"
accepts_nested_attributes_for :workout_sets, allow_destroy: true
accepts_nested_attributes_for :warmup, allow_destroy: true
end
workout_set.rb
class WorkoutSet < ActiveRecord::Base
has_and_belongs_to_many :workout_steps, :join_table => :sets_steps, dependent: :destroy
has_and_belongs_to_many :workouts, :join_table => :workout_sessions
accepts_nested_attributes_for :workout_steps, allow_destroy: true
has_one :intro_video_usage, class_name: 'VideoUsage::Intro', as: :parent, dependent: :destroy
has_one :intro_video, through: :intro_video_usage, source: :video
accepts_nested_attributes_for :intro_video
has_one :get_ready_video_usage, class_name: 'VideoUsage::GetReady', as: :parent, dependent: :destroy
has_one :get_ready_video, through: :get_ready_video_usage, source: :video
has_one :congrats_video_usage, class_name: 'VideoUsage::Congratulations', as: :parent, dependent: :destroy
has_one :congrats_video, through: :congrats_video_usage, source: :video
end
and
workout_step.rb
class WorkoutStep < ActiveRecord::Base
has_and_belongs_to_many :workout_sets, :join_table => :sets_steps
has_many :main_video_usage, class_name: 'VideoUsage::Main', as: :parent
has_many :main_videos, through: :main_video_usage, source: :video
accepts_nested_attributes_for :main_videos
end
And using simple_form and cocoon to handle nested models creation on the top level model (Workout) I'm having troubles building the form for sets and steps - more concise, when associating a workout_set with an intro_video (and whitelisting the params) I'm having the following error:
Video(#70285207226600) expected, got String(#70285080848240)
The params object after sending looks like this:
"workout"=>{"title"=>"",
"workout_sets_attributes"=>{"0"=>{"_destroy"=>"false",
"intro_video"=>"70",
"title"=>""}}},
"image"=>"",
"sound_logo"=>"",
"intro_video"=>"",
"commit"=>"Create workout"}
Thanks in advance.
Your parameters are passing a string ("70") to intro_video= but association accessors like that expect you to pass an actual instance of the associated class (in this case Video).
You should instead be assigning to intro_video_id. The accessor will convert the string to an integer for you.
I'm trying to create way for Users to Like content in my project. To do this I set up a polymorphic relationship as follows
Likes table
table "likes", force: :cascade do |t|
t.integer "likeable_id"
t.string "likeable_type"
t.integer "user_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
models
class User < ActiveRecord::Base
has_many :likes, dependent: :destroy
has_many :newsletters, through: :likes, source: :likeable, source_type: "newsletter"
has_many :gift_cards, through: :likes, source: :likeable, source_type: "gift_card"
has_many :stories, through: :likes, source: :likeable, source_type: "story"
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :likeable, polymorphic: true
end
class Newsletter < ActiveRecord::Base
has_one :like, as: :likeable, dependent: :destroy
has_one :user, through: :like, source: :likeable
end
class GiftCard < ActiveRecord::Base
has_many :likes, as: :likeable, dependent: :destroy
has_many :users, through: :likes, source: :likeable
end
class Story < ActiveRecord::Base
has_many :likes, as: :likeable, dependent: :destroy
has_many :users, through: :likes, source: :likeable
end
tldr: a User has many Likes and many Newsletters, GiftCards, and Stories through those Likes.
My question, with this structure, whats the best way to get everything a User has liked?
For me this is extremely hard to follow for a domain with is in reality is quite straightforwards. Perhaps you have a bigger reason to implement it is this way but here's my suggestion for the User Like and GiftCard models (which may or may not help!).
class User < ActiveRecord::Base
has_many :likes, dependent: :destroy
has_many :liked_giftcards, through: :likes, source: :giftcard
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :giftcard
end
class GiftCard < ActiveRecord::Base
has_many :likes, dependent: :destroy
end
class Story < ActiveRecord::Base
...same as GiftCard
end
Personally I would find this easier to follow. It provides easy access to everything a user has liked through user.likes and allows you to look at each category individually through user.liked_giftcards etc.
Ended up figuring it out. Just had some small syntactical errors
class User < ActiveRecord::Base
has_many :likes, dependent: :destroy
has_many :newsletters, through: :likes, source: :likeable, source_type: "Newsletter"
has_many :gift_cards, through: :likes, source: :likeable, source_type: "GiftCard"
has_many :stories, through: :likes, source: :likeable, source_type: "Story"
end
class Like < ActiveRecord::Base
belongs_to :user
belongs_to :likeable, polymorphic: true
end
class Newsletter < ActiveRecord::Base
has_one :like, as: :likeable, dependent: :destroy
has_one :user, through: :like
end
class GiftCard < ActiveRecord::Base
has_many :likes, as: :likeable, dependent: :destroy
has_many :users, through: :likes
end
class Story < ActiveRecord::Base
has_many :likes, as: :likeable, dependent: :destroy
has_many :users, through: :likes
end
How to write this:
has_many :sales, foreign_key: :buyer_id, dependent: :destroy
has_many :purchased_books, class_name: 'Book', through: :sales, source: :book
as this:
has_many :purchases, class_name: 'Sale', foreign_key: :buyer_id, dependent: :destroy
has_many :purchased_books, class_name: 'Book', through: :sales, source: :book
It gives me the following error at the moment:
Could not find the association :sales in model User (ActiveRecord::HasManyThroughAssociationNotFoundError)
And writing it has_many :sales is grammatically incorrect when foreign_key: :buyer_id.
The :through key must reference an association that is defined.
has_many :purchases, class_name: 'Sale', foreign_key: :buyer_id, dependent: :destroy
has_many :purchased_books, class_name: 'Book', through: :purchases, source: :book
I am trying to add a counter cache on a a column in a self join association.
I have two models User and followings. User has followers and followees, who are from the user table itself.
User.rb
has_many :followings
has_many :followers, :through => :followings
has_many :followees, :through => :followings
Following.rb
class Following < ActiveRecord::Base
attr_accessible :followee_id, :follower_id
belongs_to :follower, :class_name => "User"
belongs_to :followee, :class_name => "User"
end
now i want to add counter cache on follower and followees. I have followers_count and followees_count columns in user table.
I tried
belongs_to :follower, :class_name => "User" , :counter_cache => true
But this doesn't return any data in the user table.
Any help would be appreciated.
It was long-long time ago, but
User.rb
class User < ActiveRecord::Base
has_many :followings_as_follower, class_name: 'Following', foreign_key: 'follower_id', dependent: :destroy
has_many :followings_as_followee, class_name: 'Following', foreign_key: 'followee_id', dependent: :destroy
has_many :followers, through: :followings_as_followee, source: :follower
has_many :followees, through: :followings_as_follower, source: :followee
def follow?(user)
followees.reload.include? user
end
def follow(user)
return if follow?(user)
followings_as_follower.create(followee: user)
end
def unfollow(user)
return unless follow?(user)
followings_as_follower.where(followee: user).first.destroy
end
end
Following.rb
class Following < ActiveRecord::Base
belongs_to :follower, class_name: 'User', counter_cache: :followees_count
belongs_to :followee, class_name: 'User', counter_cache: :followers_count
validates :follower, presence: true
validates :followee, presence: true
validates :followee, uniqueness: { scope: [:follower, :followee] }
end
Try this,
belongs_to :follower, foreign_key: 'the_id_of_foreign_key', class_name: 'User', counter_cache: :followers_count
You can use the column_name instead of true in counter_cache.