【问题标题】:How to include if a post was liked by the current user in rails?如何在rails中包含当前用户是否喜欢帖子?
【发布时间】:2017-05-11 00:03:29
【问题描述】:

所以我有一个查询,获取所有最近的帖子

posts = Post.where(public: true).limit(25).order(created_at: :desc)

返回我需要的帖子。现在我想返回帖子,但我也想包括拨打电话的用户是否喜欢该帖子。

我有一个类似的表,它只有 post_id 和 user_id。

现在我拥有它的方式是

render :json => posts.as_json(:include => [:likes])

返回所有喜欢帖子的人,这不是我想要的:

{
    "id": 43,
    "title": "asdfasdfs",
    "story": "adfaf sdf sd asdf sdf asdf saf adf",
    "created_at": "2017-05-10T22:40:54.587Z",
    "updated_at": "2017-05-10T23:18:47.653Z",
    "user_id": 8,
    "likes": [
      {
        "id": 1,
        "user_id": 4,
        "post_id": 43
      },
      {
        "id": 2,
        "user_id": 6,
        "post_id": 43
      }
    ]
  }

我要么只想包含用户的类似内容(不知何故有一个包含来限制它)

或者以某种方式将其设置为 JSON 中的一个名为 like_by_me 的变量,设置为 true 或 false。我试图避免手动绘制地图并再进行 25 个查询,每个帖子一个查询是否被某人喜欢。最好的方法是什么?

谢谢

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    您应该使用当前用户的 id 和帖子 id 查询多对多表,如果该记录存​​在,则表示该用户喜欢该帖子。存储类似于您存储帖子的方式,但添加用户 ID 和帖子 ID 的 where 子句。如果该行存在,则返回该行,如果不存在,则返回 nil。

    【讨论】:

    • 但这就是我试图避免的。我可以很容易地做一个posts.map{|p| p.is_liked = Like.exists(user_id: uid, post_id: pid) } 但这意味着每个 api 调用需要 26 个查询
    • 我看不到这个问题的其他解决方案,这是查询多对多关系的方法
    【解决方案2】:

    我有类似的“问题”(我有文章而不是帖子,但没关系)。我选择的处理方式如下:

    用户模型如下所示:

    class User < ActiveRecord::Base
      has_many :articles ,dependent: :destroy 
      has_secure_password
      has_many :likes 
    end
    

    文章型号:

    class Article < ActiveRecord::Base
        belongs_to :user
        has_many :likes
    end
    

    和类似的模型:

    class Like < ActiveRecord::Base
      belongs_to :article
      belongs_to :user
    end
    

    喜欢的控制器应该是这样的:

    def create
      @like=Like.new(article_id:params[:article_id],user_id:params[:user_id])
    
      if !(Like.find_by(user_id: params[:user_id], article_id: params[:article_id]))
         if current_user!=Article.find(params[:article_id]).user
           if @like.save
             flash[:success]='Thanks for your like'
             redirect_to article_path(params[:article_id])
           else
             render 'new'
           end
         else
           flash[:warning]="You can't like your article"
           redirect_to article_path(params[:article_id])
         end
      else
         flash[:danger]='You liked this article once'
         redirect_to article_path(params[:article_id])      
      end
    end
    

    current_user 的代码:

      def current_user
        @current_user ||=User.find(session[:user_id]) if session[:user_id]
      end
    

    在文章显示模板中,我渲染了名为“_likes”的部分模板

    <%= render 'likes' %>
    

    我认为您所问的内容显示在部分模板“_likes”的这些行中

      <% if !Like.find_by(user_id: current_user, article_id:@article.id) %>
        <img src="/assets/no_like.png">
      <% else %>
        <img src="/assets/like.png">
      <% end %>
    

    如果您已登录但尚未喜欢文章,则显示模板将如下所示: Article with no like from the user logged in

    另一种情况: 如果您已登录并且喜欢该文章,则显示模板将如下所示: Article with like from you

    希望对你有帮助。

    【讨论】:

      【解决方案3】:
      class User < ActiveRecord::Base
        has_many :articles ,dependent: :destroy 
        has_secure_password
        has_many :likes 
      end
      
      class Article < ActiveRecord::Base
          belongs_to :user
          has_many :likes
      
          def liked?(user)
            !!self.likes.find{|like| like.user_id==user.id}
          end
      
      end
      
      class Like < ActiveRecord::Base
        validates :user_id, uniqueness: { scope: [:article_id]}
        belongs_to :article
        belongs_to :user
      end
      

      然后你检查:

      if @article.liked?(@current_user)
      

      参考: https://medium.com/swlh/how-to-add-a-simple-like-button-to-your-rails-6-application-c1040999dc2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-12
        • 2018-01-16
        • 1970-01-01
        • 2021-03-02
        • 1970-01-01
        • 2018-10-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多