ID
Firstly, you won't need to use :group_id
in your user_posts
model / table
Rails, and relational databases, use primary keys
to give elements unique id's. This means regardless of whether a post
is a member of a group
, you'll still be referencing it with the post_id
foreign key -
#users_posts
id | user_id | post_id | read | updated | created_at | updated_at
--
Attributes
add the attributes from user_posts
to each record in @posts
The way to do this will be to associate user_posts
with the User
and 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 will allow you to call @user.posts
If you want to attach extra attributes to each post
associative object, you'll need to either use an ALIAS SQL join, or an 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 do |caption|
proxy_association.target << read
end
end
#Private
private
#Attributes
def captions
return_array = []
through_collection.each_with_index do |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 is I think your system will be best run like this:
1. Set up a semi-persistent data store to track user / post reads (REDIS)
2. Every time you call a `Post`, you'll be able to call the associated `REDIS` references for it
This will give you the ability to create a system which is firstly modular, but you can also create an instance method to determine whether a user has read the post or not, like this:
#app/models/post.rb
Class Post < ActiveRecord::Base
def read?
##Redis lookup for user with post - if "read" attribute is true, return true
end
def liked?
##Redis lookup for user with post - if "liked" attribute is true, return true
end
end
This will allow you to run @user.posts.first.read?