Ruby on rails 在一个http请求和一个控制器(rails)中发布和删除

Ruby on rails 在一个http请求和一个控制器(rails)中发布和删除,ruby-on-rails,ruby,ruby-on-rails-4,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 4,Ruby On Rails 5,我正在用rails构建一个api,目前正在尝试为帖子实现heart/Unhear特性。此功能的工作方式是,如果用户插入帖子,数据库中将显示一个新条目(一个用户只能插入帖子一次),如果用户未听到,则该条目将被删除。目前,我在前端检查用户是否喜欢它,并发送正确的HTTP请求进行POST或DELETE。但是,这不是很有效,我想知道是否有更好的方法可以在后端(控制器或模型)上自动完成,并且只有一个http请求(例如POST) heart.rb型号: class Heart < Applicatio

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

heart.rb型号:

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 
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\u 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
Rails.application.routes.draw do
 match 'heart', to: 'hearts#heart', via: :post
 match 'unheart', to: 'hearts#unheart', via: :delete

end

正如你所看到的,我需要先检查它是否用心,然后我才需要发送正确的帖子或删除请求。是否有一种更有效的方法只发送一个请求,然后在rails内部检查它是否正确,并从一个控制器发布/删除

我建议您只有一条路由可以侦听帖子的
补丁
方法。比如:

patch '/posts/:id/heart' => 'posts#heart_post', as: :heart_post
PostsController
中执行
heart\u post
操作,而不是
hearts controller
,使用您的帖子和当前用户,并将您的帖子放在心上(无论当前状态如何,无论是否心满意足)

然后,您的
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

此操作应该只有一条路径。

这似乎是错误的节省。当你呈现一篇文章时,你必须确定用户是否已经“热心”了一篇文章,所以生成一个指向正确路线的链接不需要花费任何费用。非常感谢!这正是我想做的,但我自己却不明白。
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