How to structure association between users and posts, if we need to track users' interaction with posts

时间:2015-10-29 11:08:59

标签: ruby-on-rails database

I have an app that only displays posts that people haven't seen before so everytime a user opens an article, I need to set the seen_flag to true for this user/post combination.

Is the right approach to set it as a M:M relationship with the join table storing that interaction? Or should it still be 1:M?

EDITTED

Here are my associations between user and article. An user can create an article, but many users can view an articles, and and article has many viewed users, so I need both a has_many through and belongs_to association

class Article < ActiveRecord::Base
  belongs_to :user
  has_many :viewed_users, through: :article_view_histories
  has_many :article_view_histories
end

class User < ActiveRecord::Base
  has_many :articles
  has_many :viewed_articles, through: :article_view_histories
  has_many :article_view_histories
end

class ArticleViewHistory < ActiveRecord::Base
  belongs_to :viewed_users, :class_name => "User", :foreign_key => :user_id
  belongs_to :viewed_articles, :class_name => "Article", :foreign_key => :article_id
end

2 个答案:

答案 0 :(得分:1)

我使用has_many :through,虽然它在数据库上会很昂贵。

很多更好的方法是使用Redis来存储key:value posts user已查看过的posts#show对。有good article about it here

我在#app/controllers/posts_controller.rb class PostsController < ApplicationController def show # considering you're using Devise "current_user" @post = Post.find params[:id] $redis.sadd(current_user.id, @post.id) #-> this will need to change end end 操作中执行此操作:

#app/models/user.rb
class Post < ActiveRecord::Base
   def self.viewed(user, viewed=true)
      posts = $redis.get(user.id) #-> this will need to change
      where = "not" unless viewed is true
      self.where("`id` #{where} IN ?", posts)
   end
end

这将允许您在Post模型中添加一个类方法,以获取用户尚未查看的相关帖子:

#include <stdio.h>

void special_func()
{
    printf("calling special_func\n");
}

-

现在,Redis意味着临时(半持久)数据存储。这意味着您不应该依赖它来获得长期解决方案。相反,你可能希望&#34; dump&#34;将redis数据转换为数据表,或者如果您丢失则将其丢弃,然后将其永久保存在Redis中。

我可以根据要求为您提供更多信息。

答案 1 :(得分:0)

您还可以创建另一个名为viewings的表,其中包含user_id,post_id和已查看的标记。