为新的,编辑更新和创建操作加载其他模型集合的rails方式是什么?

如何在新的,编辑更新和创建操作中为ProductController加载Category模型的最佳方式

产品有类别集合

class Product < ActiveRecord::Base has_many :categories end 

始终用于新建,编辑,创建和更新操作,我需要加载类别集合以填充check_box_tag列表

这种情况的“婴儿步骤”是:

 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 

我不想为了相同的目的在不同的情况下加载总是Category.all

选项:

首先 – 在视图上加载类别:

  
  • :/

    第二 – 在ProductsHelper上加载类别:

     module ProductsHelper def categories Category.all end end 

    :/

    “第三” – 存在像’before_render’这样的filter?

     class Admin::ProductsController < Admin::AdminApplicationController before_render :load_categories :edit, :new def load_categories @categories = Category.all end end 

    :D:D:D

    这种情况的轨道方式是什么?

    最诚挚的问候,Pablo Cantero

    在您的控制器中,或者如果需要,在application_controller.rb中:

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

    第一次调用它时,它将命中db,稍后它将返回控制器实例变量。

    我更希望你的第三个解决方案。 我不喜欢在视图中使用业务逻辑,因为我猜收集信息是控制器的任务,在视图层我只想使用数据和辅助方法。 当您使用缓存时,在视图层中使用Category.all可能会很好,但在这种情况下,如果更改,您应该以某种方式发送过期信号。

    您的第一个解决方案有许多重复的行,您可以使用第三个解决方案擦除它们。 所以我会选择第三个:)

    在这种情况下,我会选择第一个选项。

    编辑

    正如我在评论中提到的,这取决于具体情况。 对我来说一个相对干净的方法是在控制器中定义一个categories方法并将其声明为帮助器。 然后在视图中需要时调用它。

    然而(这是我在第一次回答时设想的情况)如果它是一个单独的表单字段,我只是为了简单起见只是从视图中调用模型 – 像

     helper_method :all_categories private def all_categories Category.all end 

    并不是最优雅的代码。