【问题标题】:How to display create page/form within a separate controllers show page?如何在单独的控制器显示页面中显示创建页面/表单?
【发布时间】:2018-11-01 06:27:27
【问题描述】:

我希望能够直接从列表显示页面创建订单,而不必被定向到新的订单页面。

我有一个列表(listingcontroller show 方法),可以通过单击按钮转到订单页面(orderscontroller 创建方法)来购买。

我可以通过什么方式直接在列表显示页面上获得订单?

我尝试添加表单,但出现错误:

First argument in form cannot contain nil or be empty
<%= form_for([@listing, @order]) do |form| %>

当我使用 Orders 控制器的 create 方法并将其放入 Listings Controller Show 方法中时,我得到了这个错误:

Couldn't find Listing without an ID

这是我想要的列表显示页面中的 form_for:

    <%= form_for([@listing, @order]) do |form| %>
....

订单控制器创建:

    @order = Order.new(order_params)
    @listing = Listing.find(params[:listing_id])
    @seller = @listing.user
    @order.listing_id = @listing.id
    @order.buyer_id = current_user.id
    @order.seller_id = @seller.id

...

路线:

  resources :listings do
    resources :orders
end

上市模式:

  has_many :orders

类别型号:

  has_and_belongs_to_many :listings

我尝试使用“def create”和不使用“def create”将订单创建方法注入到 Listings show 方法中。我把“@listing = Listing.find(params[:listing_id])”放在create方法之前(当使用“def create”时,我仍然会得到它需要一个id的错误。即使我得到那个错误,在网页底部的请求显示列表 ID 在那里。

我尝试在表单中使用隐藏字段,但对我不起作用。

我是否需要对控制器做点什么,或者有没有办法以某种方式将 :listing_id 加载到表单中。这对你们中的一些人来说可能是非常快速和简单的事情,但为什么它不会在列表显示页面上加载,但在订单创建页面中加载正常?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    简单的方法。

    listing_controller.rb 中的显示操作应包含以下代码:

    def show
      @listing = Listing.find(params[:listing_id])
      @order  = @listing.orders.build
      .
      .
      .
    end
    

    您的视图/列表/show.erb 应具有以下代码

    <%= form_for(@order, url: listing_orders_path(@listing)) do |f| %> 
    . 
    . 
    . 
    <%= end %>
    

    通过这种方式,您可以在提交表单之前为列表创建一个订单(在内存中)。您可以将列表 ID 添加为隐藏字段。

    提交订单后,您可以这样修改 orders_controller.rb

    def create
       @listing = Listing.find(params[:listing_id])
       @order = @listing.orders.build(params[...]) #select the params you need for the order creation. Since you create the order directly to the listing you don't need to add the listing_id to the order.
    
       if @order.save
                #do something
       else
                #do something
       end
    end
    

    请记住,直接使用 params[] 会有安全问题,请检查批量分配:https://guides.rubyonrails.org/v3.2.8/security.html

    【讨论】:

    • 使用 params 中的单个参数不是安全问题。问题是当您将整个参数哈希分配给模型而不将其列入白名单时。所以原始代码很好 - 但你的有一个批量分配漏洞。
    • 谢谢,我知道我的代码有批量分配,这就是我参考安全指南的原因,否则我应该声明一些额外的方法来允许属性不是解决方案的事实。
    • 为什么我仍然收到相同的错误:“找不到没有 ID 的列表”...然后我在订单控制器中将其定义为:@order.listing_id = @listing.id 但是然后我收到错误消息:“nil:NilClass 的未定义方法 `id'”----我还尝试使用隐藏类 :listing_id 它通过正确的listing_id 传递参数
    • 我不介意看看你的作品,但我无法创建聊天,也许你可以在这里粘贴你的 github 存储库
    • 好的,我正在查看您的存储库
    【解决方案2】:

    您可以通过使用AJAX 调用来实现这一点,您将在其中传递orders 操作的url 和其他参数。不会重新加载页面,您将在列表页面上获得该功能。

    Here 是查看的链接 - AJAX 调用如何工作。

    【讨论】:

    • 这可以工作,但我仍然需要重新编码我的控制器才能像这样工作,因为我会将表单从订单控制器呈现到列表控制器显示页面
    • 调用什么控制器以及从哪里调用都没有关系。您只需将 url 传递给 AJAX 调用,它就会起作用。尝试采取一些关于此的教程。我很高兴它会帮助你:)
    猜你喜欢
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2019-10-25
    • 2021-01-19
    相关资源
    最近更新 更多