【问题标题】:POST and DELETE in one http request and from one controller (rails)在一个 http 请求和一个控制器(rails)中发布和删除
【发布时间】:2018-03-17 00:55:22
【问题描述】:

我正在使用 rails 构建一个 api,目前正在尝试为帖子实现 heart/unheart 功能。此功能的工作方式是,如果用户喜欢该帖子,则数据库中会显示一个新条目(一个用户只能将帖子心脏一次),如果用户取消它,则该条目将被删除。目前,我在前端检查用户是否愿意,并发送正确的 HTTP 请求以进行 POST 或 DELETE。但是,它的效率不是很高,我想知道是否有更好的方法可以在后端(控制器或模型)上自动完成,并且只有一个 http 请求(例如 POST)?

heart.rb Model:

class Heart < ApplicationRecord
  belongs_to :user
  belongs_to :post

  validates :post_id, presence: true
  validates :user_id, presence: true

  validates :user_id, uniqueness: { scope: :post_id }

end 

user.rb Model:

class User < ApplicationRecord
    has_many :posts, dependent: :destroy
    has_many :hearts, dependent: :destroy

    def heart!(post)
        self.hearts.create!(post_id: post.id)
    end

    def unheart!(post)
        heart = self.hearts.find_by_post_id(post.id)
        heart.destroy!
    end
end  

hearts_controller.rb

class HeartsController < ApplicationController

    def heart
        @user = current_user
        @post = Post.find(params[:post_id])
       if @user.heart!(@post)
       end
    end

    def unheart
         @user = current_user
         @heart = @user.hearts.find_by_post_id(params[:post_id])
         @post = Post.find(params[:post_id])
        if @heart.destroy!
        end
    end


end

routes.rb

Rails.application.routes.draw do
 match 'heart', to: 'hearts#heart', via: :post
 match 'unheart', to: 'hearts#unheart', via: :delete

end

如您所见,我需要先检查它是否有心,然后才需要发送正确的 POST 或 DELETE 请求。有没有一种更有效的方法来只发送一个请求,然后在 Rails 内检查它是否有心,然后从一个控制器中发布/删除?

【问题讨论】:

  • 这似乎是一种虚假的储蓄。当您呈现该帖子时,您将必须确定用户是否已经“关注”该帖子,因此生成指向正确路线的链接不应该花费您任何费用。

标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-5


【解决方案1】:

我建议您只有一个路由来侦听 PATCH 方法的帖子。比如:

patch '/posts/:id/heart' => 'posts#heart_post', as: :heart_post

而不是HeartsController,在PostsController 中实施heart_post 操作,获取您的帖子和当前用户并关注您的帖子(无论当前状态如何,无论是否关注)。

def heart_post
    @post = Post.find(params[:id])
    @post.heart_action(@current_user.id)

    # whatever you want to render
end

然后,您的 Post 模型将包含其自身的逻辑,并且它会知道它是否需要执行心脏或非心脏动作。

def heart_action (user_id)
    heart = Heart.find_by(user_id: user_id, post_id: self.id)

    if heart
        heart.destroy
    else
        Heart.create(user_id: user_id, link_id: self.id)
    end
end

这个动作应该只有一个路由。

【讨论】:

  • 非常感谢!这正是我想做的,但我自己搞不清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
  • 2018-05-14
  • 1970-01-01
相关资源
最近更新 更多