Rails的命名约定,用于显示表单的动作和处理表单的其他动作

时间:2019-07-15 16:44:38

标签: ruby-on-rails rails-routing

我需要创建两条路线。第一个是显示特定表单的GET路由,另一个是处理该表单的POST路由。

例如,我需要创建一条路线,以显示允许销售人员退订交易的表格。

那么,您如何命名这些路线。您是否创建类似这样的内容?

get 'deals/:id/unsubscription', to: 'deals#unsubscription'
post 'deals/:id/unsubscribe', to: 'deals#unsubscribe'

或者您是否创建像这样的一条路线:

match 'deals/:id/unsubscribe', to: 'deals#unsubscribe', via: [:get, :post]

并根据请求方法将逻辑置于相同的动作中。

3 个答案:

答案 0 :(得分:1)

另一种方法是将其声明为RESTful资源,就像其他任何资源一样经过CRUD:

GET /deals/:deal_id/subscriptions/new # form to subscribe 
POST /deals/:deal_id/subscriptions # subscribe
GET  /subscriptions/:id # view with button/form to unsubscribe
DELETE /subscriptions/:id # unsubscribe

您可以通过以下方式做到这一点:

resources :deals
  resources :subscriptions, shallow: true, only: [:show, :new, :create, :destroy] 
end

这遵循rails约定,并对非惯用操作使用正确的HTTP方法。例如,POST有望创建使POST /deals/:id/unsubscribe值得信赖的资源-DELETE /deals/:id/unsubscribe更好。

通常,最好是使用一个响应不同HTTP方法的单一控制器方法,因为它具有较高的循环复杂性。理想情况下,每种方法都应完成一项工作。

每个控制器还应代表一个资源,这会使同一控制器中的交易和订阅受到干扰是一个坏主意。

控制器只是您对磨机嵌套资源的运行:

class SubscriptionsController < ApplicationController
  before_action :set_subscription, only: [:show, :destroy]
  before_action :set_deal, only: [:new, :create]

  # GET /deals/:deal_id/subscriptions/new
  def new
    @subscription = @deal.subscriptions.new
  end

  # POST /deals/:deal_id/subscriptions/new
  def create
    @subscription = @deal.subscriptions.new(subscription_params)
    if @subscription.save
      redirect_to @subscription
    else
      render :new
    end
  end

  # GET /subscriptions/:id
  def show
  end

  # DELETE /subscriptions/:id
  def destroy
    @subscription.destroy
    redirect_to @subscription.deal
  end

  def set_subscription
    @subscription = Subscription.includes(:deal).find(:id)
  end

  def set_deal
    @deal = Deal.find(params[:deal_id])
  end

  def subscription_params
    params.require(:subscription)
          .permit(:foo, :bar)
  end
end

答案 1 :(得分:0)

您可以使用member路线帮助器。

  

要添加成员路由,只需在资源块中添加一个成员块:

resources :deals do
  member do
    get : unsubscription
    post :unsubscribe
  end
end

如果通过如下所示的其他控制器处理它,则可以做得更好:

resources :deals do
  resources :unsubscriptions,
            only: [:new, :create],
            controller: "deals/unsubscriptions"
end

现在创建一个如下所示的命名空间控制器:

Deals::UnsubscriptionsController < ApplicationController
  def new; end # renders the form.
  def create; end # this process the form submission.
end

以上路线为您创建了易于阅读的网址:

deal_unsubscriptions    POST   /deals/:deal_id/unsubscriptions(.:format)          deals/unsubscriptions#create
new_deal_unsubscription GET    /deals/:deal_id/unsubscriptions/new(.:format)      deals/unsubscriptions#new

答案 2 :(得分:0)

将GET和POST请求都路由到单个操作会带来安全隐患。通常,除非有充分的理由,否则应避免将所有动词传递给行动。 我认为您可以使用含义相似的不同动词来实现约定以及用户的可读性和可理解性。

get 'deals/:id/retract', to: 'deals#retract'
post 'deals/:id/unsubscribe', to: 'deals#unsubscribe'