加载其他模型集合以进行新建、编辑更新和创建操作的 Rails 方法是什么?

发布于 2024-10-05 00:43:27 字数 1745 浏览 5 评论 0原文

如何加载类别模型的最佳方式,对于 ProductController 中的新建、编辑更新和创建操作

产品具有类别集合

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

选项:

第一 - 在视图上加载类别:

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

:/

第二 - 在 ProductsHelper 上加载类别 :

module ProductsHelper

  def categories
   Category.all
  end

end

:/

"第三" -是否存在像“before_render”这样的过滤器?

class Admin::ProductsController < Admin::AdminApplicationController

  before_render :load_categories :edit, :new

  def load_categories
    @categories = Category.all
  end

end

:D :D :D

这种情况下的 Rails 方式是什么?

此致, 巴勃罗·坎特罗

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

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

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

发布评论

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

评论(3

爱的十字路口 2024-10-12 00:43:27

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

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

第一次调用它时,它将访问数据库,稍后它将返回控制器实例变量。

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.

冰之心 2024-10-12 00:43:27

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

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

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 :)

零時差 2024-10-12 00:43:27

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

编辑

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

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

helper_method :all_categories
private
def all_categories
  Category.all
end

并不完全是最优雅的代码。

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.

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