What's the rails way to load other models collections for new, edit update and create actions?

前提是你 提交于 2019-12-31 05:02:07

问题


How is the best way to load Category model, for ProductController in new, edit update and create actions

Product has categories collection

class Product < ActiveRecord::Base
  has_many :categories
end 

Always for new, edit, create and update actions, I need to load the categories collection to populate a check_box_tag list

The "baby steps" for this situation is:

class Admin::ProductsController < Admin::AdminApplicationController

 def new
   @product = Product.new
   @categories = Category.all
 end

 def edit
   @product = Product.find(params[:id])
   @categories = Category.all
 end

 def create
   @product = Product.new(params[:product])
   if @product.save
     flash[:notice] = 'Product was successfully created'
     redirect_to edit_admin_product_path(@product)
   else
     @categories = Category.all
     render :new
  end
 end

 def update
   @product = Product.find(params[:id])
   @product.update_attributes(params[:product])
   if @product.save
     flash[:notice] = 'Product was successfully updated'
     redirect_to edit_admin_product_path(@product)
   else
     @categories = Category.all
     render :edit
   end
 end
end 

I don't want to load always Category.all in different situations for same purpose

Options:

First - load categories over the view:

<% Category.all.each do |cat| %>
  <li>
    <%= check_box_tag .... %>
  </li>
<% end %>

:/

Second - load categories over the ProductsHelper :

module ProductsHelper

  def categories
   Category.all
  end

end

:/

"Third" - Exist a filter like 'before_render'?

class Admin::ProductsController < Admin::AdminApplicationController

  before_render :load_categories :edit, :new

  def load_categories
    @categories = Category.all
  end

end

:D :D :D

What's the rails way for this situations?

Best Regards, Pablo Cantero


回答1:


In your controller, or if needed elsewhere, in application_controller.rb:

def all_categories
  @all_categories ||= Category.all
end
helper_method :all_categories

The first time it's called, it will hit the db, and later it will return the controller instance variable.




回答2:


I would prefer your third solution. I don't like using business logic in view, because I guess gathering information is the controller's task, in the view layer I just want to use the data and the helper methods. Using Category.all in the view layer can be good when you're using cache, but in this case you should send an expired signal somehow if it changed.

Your first solution has many repeated lines, which you can erase by using your third solution. So I would choose the third one :)




回答3:


I'd go for the first option in this case.

Edit

As I've mentioned in the comments, it depends on the situation. A relatively clean way for me would be to define a categories method in the controller and declare it a helper. Then call that when you need it in the view.

However (and this is the situation I envisaged when first answering) if it's a single form field I'd simply call the model from the view just for the sake of simplicity - methods like

helper_method :all_categories
private
def all_categories
  Category.all
end

aren't exactly the most elegant code.



来源:https://stackoverflow.com/questions/4297269/whats-the-rails-way-to-load-other-models-collections-for-new-edit-update-and-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!