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
答案 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和已查看的标记。