假设我有一个包含两个父模型的子模型:
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方式来做它?
答案 0 :(得分:3)
最干的将是使用inherited_resources:
class TicketsController < InheritedResources::Base
belongs_to :event, :person, :polymorphic => true
end
轰......完成。但是,如果您出于某种原因无法使用inherited_resources,而不是get_person
或get_event
,您可以像get_parent
那样设置过滤器:
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,以解决您在评论中提到的模板问题。
答案 1 :(得分:0)
你可以这样做:
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