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

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -