【问题标题】:Ruby, Sinatra DELETE methodRuby,Sinatra DELETE 方法
【发布时间】:2023-04-10 12:14:02
【问题描述】:

我正在使用 Sinatra 编写 Shop。我实现了添加到篮子,但我无法从篮子中删除。

我的班级应用:

    get "/basket" do #working
      products_in_basket = FetchBasket.new.call
      erb :"basket/show", locals: { basket: products_in_basket }
    end

    post "/basket" do #working
      AddToBasket.new(params).call
      redirect "/"
    end


  delete "basket/:id" do # doesn't work
     DeleteBasket.new(params).call
     redirect "/"
end

我的删除篮:

module Shop
    class DeleteBasket
    attr_reader :product_id, :id

    def initialize(params)
      @id =  params.fetch("id").to_i
      @product_id = params.fetch("product_id").to_i

    end
    def call
      basket = FetchBaskets(id) # finds Basket instance with given id

      return unless basket

      reduce_basket_quantity(basket)



    def reduce_basket_quantity(basket)
      if basket.quantity >= 1
        basket.quantity -= 1
        #warehouse = FetchWarehouseProduct.new.call(product_id)
        #warehouse.quantity += quantity
      else
        BASKET.delete(basket)
      end
       end
    end
  end
end

在视图中删除:

    <td>   <form action="/basket/<%=b.id%>" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="hidden" name="product_id" value=<%= b.product_id %>>
  <input type="hidden" name="id" value=<%= b.id %>>
    <button type="submit">Delete</button>
  </form>

它没有按应有的方式重定向到主页,也没有将购物篮数量更改 1。它什么也不做。

【问题讨论】:

  • 你使用的是什么 ORM?
  • 类应该是名词,方法应该是处理所述名词的动词。有一个名为DeleteBasket 的类是没有意义的。另外,究竟是什么不起作用?你的 DeleteBasket 类在语法上甚至不正确。
  • 什么是语法错误?
  • call 方法没有匹配的end
  • 谢谢,我在复制时犯了这个错误,我在我的应用程序中已正确。问题是我被告知以这种方式上课 - 作为服务。它们是故意的动词

标签: ruby sinatra


【解决方案1】:

我认为最明显的原因是您没有调用delete http 方法,而是调用post

<form action="/basket/<%=b.id%>" method="post">

通常你会通过使用来解决这个问题

<form action="/basket/<%=b.id%>" method="delete">

但根据this answer,这还不支持。

我认为您最好的选择是将您的 delete 路由定义为 post

  post "delete-basket/:id" do
     DeleteBasket.new(params).call
     redirect "/"
  end

然后写

<form action="/delete-basket/<%=b.id%>" method="post">

【讨论】:

    【解决方案2】:

    记住我们说过,在 HTML 表单中,我们可以指定应该用于发出请求的 HTTP 动词,如下所示:

    <form action="/monstas" method="post">
      ...
    </form>
    

    这使得表单 POST 到 /monstas,而不是默认的 GET。

    现在,可以公平地说,世界上每个理智的人都会期望也可以发出 PUT 或 DELETE 请求。像这样:

    <form action="/monstas" method="delete">
      ...
    </form>
    

    除了……它不是。今天的浏览器仍然不允许使用除 GET 和 POST 之外的任何其他动词发送 HTTP 请求。

    2015 年仍然如此的原因要么令人着迷,要么令人悲伤,这取决于您如何看待它 [1] 但现在我们只需要接受这一点,并解决它。

    因此,Sinatra(以及 Rails 和其他框架)支持“伪造”请求,使其看起来像是应用程序端的 PUT 或 DELETE 请求,尽管实际上它们都是 POST 请求。

    这是通过向表单添加隐藏的表单输入标签来实现的,如下所示:

    <input name="_method" type="hidden" value="delete" />
    

    来源:https://webapps-for-beginners.rubymonstas.org/resources/fake_methods.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 2017-05-20
      • 1970-01-01
      相关资源
      最近更新 更多