Rails - 与两个父母嵌套资源

时间:2010-09-06 17:30:47

标签: ruby-on-rails nested-resources

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

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方式来做它?

2 个答案:

答案 0 :(得分:3)

最干的将是使用inherited_resources:

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

轰......完成。但是,如果您出于某种原因无法使用inherited_resources,而不是get_personget_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