ruby on rails - When to add records to a user_posts table to track 'likes' -
i have groups model has_many
topics. topics model has_many
posts, users model read posts etc. have users_posts model used keep track whether user has read post , whether 'liked' post, has :group_id, :user_id , :read , :liked boolean fields. user creates group , adds posts under different topics.
the groups show action is; @posts = group.topics.includes(:posts)
my question when , how add records users_posts table? should when post first created? or when user views post first time?
and best way add attributes user_posts each record in @posts? @ minute i'm using virtual attributes, right way?
class post < activerecord::base belongs_to :topic has_many :users, through: :user_entries attr_accessor :read, :liked
id
firstly, won't need use :group_id
in user_posts
model / table
rails, , relational databases, use primary keys
give elements unique id's. means regardless of whether post
member of group
, you'll still referencing post_id
foreign key -
#users_posts id | user_id | post_id | read | updated | created_at | updated_at
--
attributes
add attributes
user_posts
each record in@posts
the way associate user_posts
user
, post
models -
#app/models/user.rb class user < activerecord::base has_many :user_posts has_many :posts, through: :user_posts end #app/models/post.rb class post < activerecord::base has_many :user_posts has_many :users, through: :user_posts end
this allow call @user.posts
if want attach attributes each post
associative object, you'll need either use alias sql join, or activerecord association extension
:
#app/models/post.rb class user < activerecord::base has_many :user_posts has_many :posts, through: :user_posts, extend: postuser end #app/models/concerns/post_user.rb module postuser #load def load reads.each |caption| proxy_association.target << read end end #private private #attributes def captions return_array = [] through_collection.each_with_index |through,i| associate = through.send(reflection_name) associate.assign_attributes({read: items[i]}) if items[i].present? return_array.concat array.new(1).fill( associate ) end return_array end ####################### # variables # ####################### #association def reflection_name proxy_association.source_reflection.name end #foreign key def through_source_key proxy_association.reflection.source_reflection.foreign_key end #primary key def through_primary_key proxy_association.reflection.through_reflection.active_record_primary_key end #through name def through_name proxy_association.reflection.through_reflection.name end #through def through_collection proxy_association.owner.send through_name end #captions def items through_collection.map(&:read) end #target def target_collection #load_target proxy_association.target end end
--
system
bottom line think system best run this:
1. set semi-persistent data store track user / post reads (redis) 2. every time call `post`, you'll able call associated `redis` references
this give ability create system firstly modular, can create instance method determine whether user has read post or not, this:
#app/models/post.rb class post < activerecord::base def read? ##redis lookup user post - if "read" attribute true, return true end def liked? ##redis lookup user post - if "liked" attribute true, return true end end
this allow run @user.posts.first.read?
Comments
Post a Comment