如何在rails中将对象从一个控制器传递到另一个控制器?

时间:2017-11-24 22:43:56

标签: ruby-on-rails ruby

如何将构建并从一个控制器的show操作提交的对象传递给另一个控制器的create操作,同时还保留前者的实例变量?

上述ItemsController:

def show
 @item = Item.friendly.find(params[:id])
 @trade = current_user.requested_trades.build
end

我的form_for页面上的show会发布@trade的帖子请求,其中:wanted_item:trade_requester为参数。

TradesController:

def create
 @item = ???
 @trade = current_user.requested_trades.build
 if @trade.save
  format.html { redirect_to @item, notice: "success" }
 else
  format.html { redirect_to @item, notice "pick another number" }
 end
 etc...
end

Trade.rb:

belongs_to :trade_requester, class_name: "User"
belongs_to :trade_recipient, class_name: "User"
belongs_to :wanted_item, class_name: "Item"
belongs_to :collateral_item, class_name: "Item"

的routes.rb

resources :trades do
 member do
  post :accept
  post :reject
 end
end

关于这个问题感觉不对?关于这个问题的其他问题似乎是关于在同一个控制器内的不同动作之间传递一个对象 - 我问的不是那个。

1 个答案:

答案 0 :(得分:1)

首先,我想我会让我的路线更像:

resources :wanted_items do 
  resources :trades, shallow: true do 
    member do 
      post :accept
      post :reject
    end
  end
end

哪会给你:

         accept_trade POST   /trades/:id/accept(.:format)                          trades#accept
         reject_trade POST   /trades/:id/reject(.:format)                          trades#reject
   wanted_item_trades GET    /wanted_items/:wanted_item_id/trades(.:format)        trades#index
                      POST   /wanted_items/:wanted_item_id/trades(.:format)        trades#create
new_wanted_item_trade GET    /wanted_items/:wanted_item_id/trades/new(.:format)    trades#new
           edit_trade GET    /trades/:id/edit(.:format)                            trades#edit
                trade GET    /trades/:id(.:format)                                 trades#show
                      PATCH  /trades/:id(.:format)                                 trades#update
                      PUT    /trades/:id(.:format)                                 trades#update
                      DELETE /trades/:id(.:format)                                 trades#destroy
         wanted_items GET    /wanted_items(.:format)                               wanted_items#index
                      POST   /wanted_items(.:format)                               wanted_items#create
      new_wanted_item GET    /wanted_items/new(.:format)                           wanted_items#new
     edit_wanted_item GET    /wanted_items/:id/edit(.:format)                      wanted_items#edit
          wanted_item GET    /wanted_items/:id(.:format)                           wanted_items#show
                      PATCH  /wanted_items/:id(.:format)                           wanted_items#update
                      PUT    /wanted_items/:id(.:format)                           wanted_items#update
                      DELETE /wanted_items/:id(.:format)                           wanted_items#destroy

然后在form_for中,我会做类似的事情:

<% form_for wanted_item_trades_path(wanted_item: @wanted_item, trade: @trade) do |f| %>
  ...
<% end %>

form_for语法可能不完全正确,因此您可能需要使用它。

这将生成类似以下内容的网址:

/wanted_items/3/trades

当然,&#39; 3&#39;刚刚组成。它将成为您@item.id的任何内容。

发布表单时,wanted_item_id的{​​{1}} params应该有3。然后,在您的TradesController中,您将执行以下操作:

class TradesController < ApplicationController

  def create
    @wanted_item = Item.find_by(id: params[:wanted_item_id])
    @trade = current_user.requested_trades.build(wanted_item: @wanted_item)
    if @trade.save
      format.html { redirect_to @item, notice: "success" }
    else
      format.html { redirect_to @item, notice "pick another number" }
    end
  end        

  ...

end
顺便说一句,看起来你正在使用friendly_id。因此,您可以调整以上所有内容以使用friendly_id代替id。我不使用friendly_id,因此您必须自行排序。