如何发送FETCH请求来执行Rails destroy_all?

时间:2017-07-20 20:10:45

标签: ruby-on-rails fetch

我想我的API知识仍然有限,因为我无法理解这一点。

我有一个位于React前端和Rails后端的应用程序。如果我想一次删除一个项目,我可以这样做:

function deleteSomething(somethingId){
  return fetch(`api/something/${somethingId}`, {
    method: 'DELETE'
  })
}

在Rails控制器中,我做了类似

的操作
  def destroy
    @something = Something.find(params[:id]).destroy
    head :no_content
  end

我的路线看起来像这样:

scope :api do
  resources :something, only: [:index, :show, :create, :update, :destroy]
  ...

这一次,我想一次销毁多个项目。我发现这个SO post谈到了destroy_all;我在我的rails控制台上进行了测试,它的效果就像魔法一样(不是Rails本身很神奇吗?)。

但是,我无法弄清楚如何编写获取方法或路由。

  def destroy
    Something.destroy_all(:name => params[:name]) #if I want to destroy all Model with certain name
  end

如何编写fetch方法?我不认为我应该包含每一个ID并逐个迭代,因为这与我想要首先使用destroy_all的原因相反。

function deleteSomehing(name){
  return fetch(`api/something/(what goes here?)`, {
    method: 'DELETE'
  })
}

我的fetch方法应该在哪里寻址/路由到?我应该如何处理路由,我应该在控制器内部为此创建一个新方法,还是可以将其存储在destroy内?

编辑: 这是我尝试过的,但它不起作用(错误:Uncaught (in promise) SyntaxError: Unexpected end of JSON input

function customDeleteName(name){
  return fetch(`api/something/delete_by_name`, {
    method: 'POST',
    headers: {
      'Content-Tye': 'application/json'
    },
    body: JSON.stringify({
      name: name
    })
  }).then((response) => response.json())
}

内部路线 - api范围:

scope :api do
      post '/something/delete_by_name' => 'something#delete_by_name'

内部控制器:

  def delete_by_name
    Something.destroy_all(:name => params[:name])
  end

EDIT2:

#routes
scope :api do
  delete `/something/delete_by_name/:name`, to: 'something#delete_by_name'

#controller
def delete_by_name
  Something.destroy_all(:name => params[:name])
  head :no_content
end


## JS side ##
#fetch:
function deleteSomething(name){
  return fetch(`api/something/delete_by_name/${name}`, {
    method: 'DELETE'
  })
}

错误:

ActionController::RoutingError (No route matches [DELETE] "/api/something/delete_by_name/somename"):

2 个答案:

答案 0 :(得分:2)

我想我会在控制器上为它创建一个特定的方法/动作。 给定模型名称,您可以:

"something".capitalize.constantize.destroy_all

如果something有两个名字,那么在调用constantize之前,你需要正确地将其大写。

scope :api do
   ...
   delete 'your/beautiful/route/:name', to: 'wherewild#thingsare'

wherewild_controller.rb

def thingsare
  #do magic rails
end

现在,如果您选择与当前删除相同的路径路径,则会出现问题,因此最好选择另一条路径。

答案 1 :(得分:0)

想出怎么做。 @Micael的答案虽然没有完全解决,但却让我走向正确的方向。非常感谢他!

我在自定义方法/路线上做了一个POST方法,它起作用了:

#controller
   def delete_by_name
     Something.destroy_all(:name => params[:name])
     head :no_content
   end

#routes: 
  post '/delete_latest_name' => 'something#delete_by_name'

#JS#
  function deleteSomething(name){
    return fetch(`delete_latest_name`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: name
      })
    });
  }