使用嵌套资源烘干Rails视图

时间:2010-03-22 21:12:18

标签: ruby-on-rails views nested-resources

如果您的模型既非嵌套又嵌套,例如产品,那么您对该问题的解决方案是什么:

  

“产品”可以归属于“事件”,而产品也可以是独立的。

这意味着我可以拥有这样的路线:

map.resources :products # /products
map.resources :events do |event|
  event.resources :products # /events/1/products
end

你如何正确处理你的观点?

注意:这适用于管理员面板。我希望能够拥有一个“创建事件”页面,其中包含用于创建票证(产品),表单和检查谁是rsvp的侧面板。所以你点击“活动门票”侧面板按钮,它会带你到/events/my-new-event/tickets。但是管理面板还有一个根“产品”选项卡,可以列出门票和其他随机产品。 “门票”和“产品”视图看起来相同,但是门票会有一些关于它所属事件的信息。

似乎我必须有这样的观点:

  • 产品/ index.haml
  • 产品/ show.haml
  • 事件/产品/ index.haml
  • 事件/产品/ show.haml

但这似乎并不干燥。或者我可以让条件检查以查看产品是否有事件(@product.event.nil?),但后来很难理解。

你如何处理这些情况?

非常感谢。

3 个答案:

答案 0 :(得分:2)

我建议您使用自己的视图创建单独的管理控制器来管理您想要的所有内容。并且您的客户的逻辑保留在产品控制器中。

答案 1 :(得分:0)

我没有这个问题的良好和干净的解决方案。通常,如果视图没有太大差异,我使用单一视图并添加一些代码,如@product.event.nil?。您可以在示例has_event?上添加一些可以缩短此方法的变量或帮助程序 - 然后您的视图看起来会更清晰。并在像这样的代码中使用它:

<% if has_event? %>
  some html
<% end %>

或单行:

<%= link_to 'Something special', foo_path if has_event? %>

另一方面,您可以为两个视图创建几个相同的部分,将它们放在某个文件夹中,例如/shared/products/...,然后从您的视图中渲染它们,如下所示:

<%= render :partial => '/shared/products/info' %>

等等。

但如果它们没有太大差异,我真的会使用if版本。

答案 2 :(得分:0)

视图将由ProductsController处理。您可以根据资源的嵌套更改控制器中的逻辑。

# app/controller/products_controller.rb
# ...some code...
def index
    @event = Event.find_by_id(params[:event_id]) if params[:event_id]
    @products = @event ? @event.products : Product.all
end

视图将由通常的产品视图处理

# app/views/products/index.html.haml
- unless @products.blank?
    - @products.each do |product|
        %p= product.some_attribute