何时将记录添加到user_posts表以跟踪“喜欢”

时间:2014-06-27 09:07:24

标签: ruby-on-rails database postgresql activerecord database-design

我有一个has_many主题的群组模型。 主题模型has_many帖子,我的用户模型只读帖子等。 我还有一个users_posts模型,用于跟踪用户是否已阅读帖子 以及他们是否喜欢'帖子,它有:group_id,:user_id和:read和:likes boolean fields。 用户创建一个组并在不同主题下添加帖子。

小组表明行动是; @posts = Group.topics.includes(:posts)

我的问题是何时以及如何将记录添加到users_posts表? 是否应该在首次创建帖子时? 或仅在用户第一次查看帖子时?

将user_posts中的属性添加到@posts中的每条记录的最佳方法是什么? 在我使用虚拟属性的那一刻,这是正确的方法吗?

class Post < ActiveRecord::Base
  belongs_to :topic
  has_many :users, through: :user_entries
  attr_accessor :read, :liked

1 个答案:

答案 0 :(得分:2)

<强> ID

首先,您不需要在:group_id模型/表格中使用user_posts

Rails和关系数据库使用primary keys为元素提供唯一ID。这意味着无论post是否是group的成员,您仍然会使用post_id foreign key -

引用它
#users_posts
id | user_id | post_id | read | updated | created_at | updated_at

-

<强>属性

  

user_posts的属性添加到@posts

中的每条记录

执行此操作的方法是将user_postsUserPost模型相关联 -

#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

这样您就可以拨打@user.posts

如果您想为每个post关联对象附加额外的属性,您需要使用ALIAS SQL joinActiveRecord 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

-

<强>系统

底线是我认为你的系统最好这样运行:

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

这将使您能够创建一个首先是模块化的系统,但您也可以创建一个实例方法来确定用户是否已阅读帖子,如下所示:

#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

这将允许您运行@user.posts.first.read?