I'm getting this error:
undefined method `create_postconversation' for #<Post...>
...originating from this line:
posts_controller.rb
#postconversation = #post.create_postconversation
What am I doing wrong?
post.rb
has_one :postconvo, foreign_key: "post_id", dependent: :destroy
has_one :postconversation, through: :postconvo,
class_name: "Conversation",
source: :conversation
postconvo.rb
belongs_to :post
belongs_to :conversation
validates :post_id, presence: true
validates :conversation_id, presence: true
conversation.rb
has_one :postconvo, foreign_key: "conversation_id", dependent: :destroy
has_one :post, through: :postconvo, source: :post
Related
I am trying to implement likes into my rails app.
like model
class Like < ApplicationRecord
belongs_to :comment
belongs_to :post
belongs_to :user
validates :user_id, uniqueness: {scope: :post_id}
validates :user_id, uniqueness: {scope: :comment_id}
end
user model
class User < ApplicationRecord
has_secure_password
has_one :profile, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :posts, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :liked_comments, :through => :likes, :source => :comment, dependent: :destroy
has_many :liked_posts, :through => :likes, :source => :post, dependent: :destroy
has_one_attached :avatar
validates :username, presence: true, uniqueness: true
validates :email, presence: true, uniqueness: true
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, length: { minimum: 8 }
validates :password, format: { with: /\A[a-zA-Z0-9!##$%^&*()_]+\z/ }
# validates :password, confirmation: true
# validates :password_confirmation, presence: true
end
post & comment model
class Post < ApplicationRecord
belongs_to :category
belongs_to :user
has_many :comments, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :liking_users, :through => :likes, :source => :user
has_many_attached :images
def liked?(user)
!!self.likes.find{|like| like.user_id == user.id}
end
end
class Comment < ApplicationRecord
belongs_to :post
belongs_to :user
has_many :likes, dependent: :destroy
has_many :liking_users, :through => :likes, :source => :user
has_many_attached :images
def liked?(user)
!!self.likes.find{|like| like.user_id == user.id}
end
end
The issue I'm having is when I run my seed data I get one of two errors NoMethodError: undefined method "marked_for_destruction?" for false:FalseClass if set up like so:
#like0 = Like.create!(
user: #admin0,
post: #post3 & #post5 & #post6 & #post8 & #post9,
comment: #comment1,
username: #admin0.username
)
or NotNullViolation: ERROR: null value in column "comment_id" violates not-null constraint if set up like so:
class Like < ApplicationRecord
belongs_to :comment, optional: true
belongs_to :post, optional: true
belongs_to :user
validates :user_id, uniqueness: {scope: :post_id}
validates :user_id, uniqueness: {scope: :comment_id}
end
#like0 = Like.create!(
user: #admin0,
post: #post3,
comment: #comment1,
username: #admin0.username
)
my question is how can I better set up the relationship between these 4 models so as to not get these errors?
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.
I have model Category (categories of Images)
class Category < ApplicationRecord
has_many :images, foreign_key: 'category_id', dependent: :destroy
has_many :subscriptions, foreign_key: "category_id", dependent: :destroy
has_many :subscribed_users, :through => :subscriptions, :source => :user
end
Model Category has many subscribtions and subscribed users
class Subscription < ApplicationRecord
belongs_to :user
belongs_to :category
validates :user_id, presence: true
validates :category_id, presence: true
end
class User < ApplicationRecord
has_many :images, foreign_key: 'user_id', dependent: :destroy
has_many :categories, foreign_key: 'user_id', dependent: :destroy
has_many :likes, foreign_key: "user_id", dependent: :destroy
has_many :liked_images, :through => :likes, :source => :images
has_many :comments, foreign_key: "user_id", dependent: :destroy
has_many :commented_images, :through => :comments, :source => :images
has_many :subscriptions, foreign_key: 'user_id', dependent: :destroy
has_many :subscribed_categories, :through => :subscriptions, :source => :categories
end
Also I have model Image
class Image < ApplicationRecord
belongs_to :user
belongs_to :category
has_many :likes, foreign_key: "image_id", dependent: :destroy
has_many :liking_users, :through => :likes, :source => :user
has_many :comments, foreign_key: "image_id", dependent: :destroy
has_many :commenting_users, :through => :comments, :source => :user
end
which has many likes and comments (comments and likes to Image, not to categories of image)
class Like < ApplicationRecord
belongs_to :user
belongs_to :image
validates :user_id, presence: true
validates :image_id, presence: true
end
class Comment < ApplicationRecord
belongs_to :user
belongs_to :image
validates :user_id, presence: true
validates :image_id, presence: true
end
I need to select from database 5 most popular categories.
The most popular category is category which has highest count of likes, comments and images at the same time.
I made one query, which select all images, that has the highest count of likes and comments:
#top_images = Image.left_outer_joins(:likes).distinct.select('images.*, COUNT(likes.*) AS likes_count').left_outer_joins(:comments).distinct.select('images.*, COUNT(comments.*) AS comments_count').group(
'images.id').order("likes_count DESC").order("comments_count DESC")
Also I make query which select categories, which has more images:
#top_categories_img_count = Category.left_outer_joins(:images).distinct.select('categories.*, COUNT(images.*) AS images_count').group(
'categories.id').order("images_count DESC")
But I have no idea how to select all categories which have highest count of images, likes and comments
I have 3 models set up as follows:
class User < ActiveRecord::Base
has_many :interests, as: :interesting, dependent: :destroy
has_many :games, through: :interests, source: :interesting, source_type: 'Game'
has_many :people, through: :interests, source: :interesting, source_type: 'Person'
end
class Interest < ActiveRecord::Base
belongs_to :interesting, polymorphic: true
validates :user_id, presence: true
validates :interesting_id, presence: true
end
class Game < ActiveRecord::Base
has_many :users, through: :interests
has_many :interests, as: :interesting
end
class Person < ActiveRecord::Base
has_many :users, through: :interests
has_many :interests, as: :interesting
end
When I try to call user.games the SQL run on the database is
SELECT "games".* FROM "games"
INNER JOIN "interests"
ON "game"."id" = "interests"."interesting_id"
WHERE "interests"."interesting_id" = $1 AND
"interests"."interesting_type" = $2 AND
"interests"."interesting_type" = $3
[["interesting_id", 3],
["interesting_type", "User"],
["interesting_type", "Game"]]
so obviously nothing is returned. The query should work, as long as ["interesting_type", "User"] isn't included.
What am I doing wrong? What is the best way to set up the User class as well as the Game and Person class?
I'm using Rails v4.2.6
So to summarize, the following appears to work in this use case:
User < ActiveRecord::Base
has_many :interests, dependent: :destroy
has_many :games, through: :interests,
source: :interesting, source_type: 'Game'
has_many :people, through: :interests,
source: :interesting, source_type: 'Person'
end
class Interest < ActiveRecord::Base
belongs_to :user
belongs_to :interesting, polymorphic: true
validates :user_id, presence: true
validates :interesting_id, presence: true
end
Please trying this
class User < ActiveRecord::Base
has_many :interests, dependent: :destroy
has_many :games, as: :interesting, through: :interests, source_type: 'Game'
has_many :people, as: :interesting, through: :interests, source_type: 'Person'
end
class Interest < ActiveRecord::Base
belongs_to :interesting, polymorphic: true
validates :user_id, presence: true # I don't know the reason to use that if you use as polymorphic
validates :interesting_id, presence: true
end
The table_name interests it should have only the attributes :id:, :interesting_id, :interesting_type
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.