Rails - 有两个父母的嵌套资源

发布于 2024-09-18 03:07:10 字数 648 浏览 5 评论 0原文

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

Event has_many tickets

Person has_many tickets

Ticket belongs_to Event
Ticket belongs_to Person

路由已映射,因此票证始终嵌套在事件或人员中:

resource :people do
  resources :tickets
end

resources :events do
  resources :tickets
end

如何按父资源确定我的 Ticket_Controller CRUD 操作的范围?

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

class TicketController

  before_filter :get_person
  before_filter :get_event

  def index
    if @person do
      ...
    elsif @event do
      ...
    end
    respond_to
      ...
    end
  end

对于每个操作来说这似乎有点乏味。有没有更 Rails-y DRY 的方法来做到这一点?

Say I have a child model with two parent models:

Event has_many tickets

Person has_many tickets

Ticket belongs_to Event
Ticket belongs_to Person

Routes are mapped so Ticket always nests within Event or Person:

resource :people do
  resources :tickets
end

resources :events do
  resources :tickets
end

How do I scope my ticket_Controller CRUD actions by the parent resource?

Right now I'm testing for params and using conditional statements:

class TicketController

  before_filter :get_person
  before_filter :get_event

  def index
    if @person do
      ...
    elsif @event do
      ...
    end
    respond_to
      ...
    end
  end

That seems a bit tedious to do for every action. Is there a more rails-y DRY way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

守望孤独 2024-09-25 03:07:51

你可以这样做:

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

You could do this:

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

There are many ways of improving the code above.

You could also write the routes as follows:

resources :people, :has_many => :tickets

resources :events, :has_many => :tickets
云之铃。 2024-09-25 03:07:42

最干燥的方法是使用继承资源:

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

Boom...done。但是,如果您出于某种原因无法使用inherited_resources,则可以为get_parent设置一个过滤器,而不是使用get_personget_event,如下所示:

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 来解决您在评论中提到的模板问题。

The most DRY would be to use inherited_resources:

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

Boom...done. If you can't use inherited_resources for whatever reason, though, rather than get_person or get_event you could set up a filter to get_parent like so:

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

Edit: I added the @template_prefix above to address the template issue you mentioned in your comment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文