Rails – 与两个父母嵌套资源

假设我有一个带有两个父模型的子模型:

Event has_many tickets Person has_many tickets Ticket belongs_to Event Ticket belongs_to Person 

路由已映射,因此Ticket始终嵌套在Event或Person中:

 resource :people do resources :tickets end resources :events do resources :tickets end 

如何根据父资源调整ticket_Controller CRUD操作的范围?

现在我正在测试params并使用条件语句:

 class TicketController before_filter :get_person before_filter :get_event def index if @person do ... elsif @event do ... end respond_to ... end end 

对于每一个动作来说,这似乎有点乏味。 有更多的轨道式DRY方式吗?

最干的是使用inherited_resources:

 class TicketsController < InheritedResources::Base belongs_to :event, :person, :polymorphic => true end 

咚……完成。 但是,如果不能出于任何原因使用inherited_resources,而不是get_personget_event你可以设置一个get_parent的filter,如下所示:

 class TicketsController < ActionController::Base before_filter :get_parent def get_parent if params[:person_id] @parent = Person.find(params[:person_id]) @template_prefix = 'people/tickets/' elsif params[:event_id] @parent = Event.find(params[:event_id]) @template_prefix = 'events/tickets/' else # handle this case however is appropriate to your application... end end # Then you can set up your index to be more generic def index @tickets = @parent.tickets render :template => @template_prefix + 'index' end end 

编辑:我在上面添加了@template_prefix来解决您在评论中提到的模板问题。

你可以这样做:

 class TicketController before_filter :get_object def index end private def get_object type = params['event_id'] ? 'event' : 'person' value = type.classify.constantize.find(params[:"#{type}_id"]) name = '@' + type instance_variable_set(name , value) end end 

有很多方法可以改进上面的代码。

您也可以按如下方式编写路线:

 resources :people, :has_many => :tickets resources :events, :has_many => :tickets