另一种方法是将其声明为 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