DRYing up Rails Views with Nested Resources

What is your solution to the problem if you have a model that is not nested and nested, for example, products:

a “Product” may belong to “say” “Event,” and the Product may also be independent.

This means that I can have these routes:

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

How do you deal with this in your views correctly?

Note: this is for admin panel. I want to have a Create Event page with a sidebar for creating tickets (Product), forms and checking who rsvp'd is. Thus, you click on the button on the sidebar "Event Tickets", and it will transfer you to /events/my-new-event/tickets . But there is also a root tab “Products” for the admin panel, which can display tickets and other random products. The “tickets” and “products” views look 90% the same, but the tickets will have some information about the event to which it belongs.

It looks like I would need to have these types:

  • Products /index.haml
  • Products /show.haml
  • Events / Products / index.haml
  • Events / Products / show.haml

But it does not seem dry. Or I could have conditional expression checks to see if the product had an event ( @product.event.nil? ), But then the views would be hard to understand.

How do you deal with these situations?

Many thanks.

+4
source share
3 answers

I recommend that you create a separate administrator controller with its own views for administering everything you want. And your customer logic has remained in contoller products.

+2
source

I do not have a good and clean solution to this problem. Usually, if the views are not much different from each other, do I use one view and add code like @product.event.nil? . You can always add some variable or helper that will make this method shorter, for example has_event? - then your presentation will look cleaner. And use it in the code as follows:

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

or for a single line:

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

On the other hand, you can create several particles that are the same for both views, put them in some folder, for example, /shared/products/... and make them from your views as follows:

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

etc.

But if they are not very different from each other, I would use the if version.

0
source

Views will be processed using the ProductsController . You can change the logic of your controller depending on the nesting of the resource.

 # 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 

The view will be processed in the normal view of the product.

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

Source: https://habr.com/ru/post/1304810/


All Articles