Three models: Post, Comment, Rating.
Post
class Post < ApplicationRecord
has_many :comments
has_many :ratings, through: :comments
end
Comment
class Comment < ApplicationRecord
belongs_to :post
has_one :rating
end
Rating
class Rating < ApplicationRecord
belongs_to :comment
end
I want to be able to do call a method on Post model (to for example calculate mean_rating) when the Rating record gets added or removed to my database.
I am able to to this with calling the post model method inside rating model after_create and after_destroy but I am wondering if there is a way to update Post model using dependent or any other methods?
Any ideas?
You could create a method in your Post model:
class Post < ApplicationRecord
has_many :comments
has_many :ratings, through: :comments
def average_rating
ratings.average(:note)
end
end
And call it on your instances:
post = Post.last
post.average_rating
Related
I have a User model, Post model and Bookmark model. How do i need to set up relationship among them so that I can use current_user.bookmarks.posts.
Maybe:
class User < ApplicationRecord
has_many :bookmarks
end
class Bookmark < ApplicationRecord
belongs_to :user
has_many :posts
end
class Post < ApplicationRecord
belongs_to :bookmark
end
If you're wanting to get all the posts that belong to the user, then you can use the has_many :through association:
class User < ApplicationRecord
has_many :bookmarks
has_many :posts, through: :bookmarks
end
class Bookmark < ApplicationRecord
belongs_to :user
has_many :posts
end
class Post < ApplicationRecord
belongs_to :bookmark
end
Then you can just call:
user = User.first
all_posts = user.posts
It will return an array containing all the posts for each of the bookmarks belonging to the user.
When I do #post = Post.first.comments.build(content: "bla", user: #user) and search via #user.comments nothing shows up. But when I do it with #post.comments, it lists the comment. How can I see my comment with both #user.comments and #post.comments?
class Post < ApplicationRecord
belongs_to :user
has_many :comments
end
my user model
class User < ApplicationRecord
has_many :posts
has_many :comments
end
comment model
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
end
use through to get comments of all posts associated with the user's posts.
class User
has_many :posts
has_many :comments, through: :posts
end
What is the best way to implement something like a board in pinterest (a collection of objects) in rails. I am trying to come with it, it seems more like an array implementation.
Here's my logic for the associations : User have many collections, user have many pins , collections belongs to user.
User class
class User < ActiveRecord::Base
has_many :pins, through: :collections
has_many :collections
end
Pins class
class Pin < ActiveRecord::Base
belongs_to :user
has_many :collections
end
Collections class
class Collection < ActiveRecord::base
belongs_to :user
end
So now here's my confusion, how to implement a controller that will allow me to create a collection and inside this collection object, create or push pins and save them as another object for the current_user. Hope I'm making sense
Here's the controller
class CollectionsController < ApplicationController
def create
#collection = current_user.collections.new(params[:collection])
#this where i'm confused , if it an array , how to implement it , to push or create a pin object inside ?
end
end
You have to use nested attributes for this.
Check this http://currentricity.wordpress.com/2011/09/04/the-definitive-guide-to-accepts_nested_attributes_for-a-model-in-rails-3/.
Basically what you need is:
# collection model
accepts_nested_attributes_for :pins
# view, see also nested_form in github
f.fields_for :pins
You're looking for the has_many_through association. See section 2.4 on the Rails guide: http://guides.rubyonrails.org/association_basics.html
class User < ActiveRecord::Base
has_many :collections
end
class Pin < ActiveRecord::Base
has_many :collections, through: :pinnings
end
class Pinning < ActiveRecord::Base
belongs_to :pin
belongs_to :collection
end
class Collection < ActiveRecord::base
belongs_to :user
has_many :pins, through: :pinnings
end
I have three models which look something like this:
Class User < ActiveRecord::Base
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
Now I want to get all the votes associated with a user's comments like so:
#user.comments.votes
But this throws the error:
undefined method `votes' for #<ActiveRecord::Relation:0x3f6f8a0>
This seems like it should work, but I suspect ActiveRecord is coughing on the deeper has_many relationship. I've hacked together an SQL query that gets the desired results, but I suspect there's a cleaner way using purely ActiveRecord. Any tips?
You should use a has_many :through association
In your case it would be
Class User < ActiveRecord::Base
has_many :comments
has_many :votes, :through => :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
And then simply get the votes with
#user.votes
Try this:
Vote.joins(comment: :user).where(users: {id: #user.id})
I was wondering how I'm suppose to associate my User, Post, and Comment models. It is suppose to be like so: The user can comment on any post and a post belongs to a user with a Boolean for being admin. I have been scratching my had for awhile trying to figure this out but nothing has made any sense at all.
Any help would be greatly appreciated.
In the most obvious arrangement Post would belong_to :user and has_many :comments, and Comment would both belong_to :user and belong_to :post. User would has_many :posts.
You can specify the following association in the model
# app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
end
# app/models/user.rb
class User < ActiveRecord::Base
has_many :comments
end
# app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end