Rails select_tag nil:NilClass 的未定义方法“映射”

Rails select_tag undefined method `map' for nil:NilClass

我的问题已经解决了,但我认为它有点笨拙,所以希望能找到更好的方法,并更好地理解这里发生的事情。

_form.html.erb:

 <%= select_tag(:category_id, options_for_select(@categories), :prompt => "Select one!") %>

products_controller.rb:

def new
  @product = Product.new
  @categories = Category.all.map { |c| [ c.name, c.id ] }
end

如果用户在未选择任何 select_tag 选项的情况下提交表单,他将收到 undefined method 'map' for nil:NilClass 错误。

我知道它会出现,因为我的 @categoriesnil,但我不知道如何避免这种情况..?

我的最终解决方案有效:

<%= select_tag(:category_id, options_for_select(@categories || Category.all.map { |c| [ c.name, c.id ] }), :prompt => "Select one!") %>

但我觉得有更好的方法。我还认为,通过为 :selected 分配默认 select_tag 值也可能有效,但我无法根据 Ruby 语法的知识来实现​​它...

请尝试select_tag的这种方式:

select_tag(:category_id, options_from_collection_for_select(Category.all, :id, :name), include_blank: "Select Category")

如果您遇到任何问题,请告诉我..

是的,你可以使用辅助方法而不是在每个视图中使用 Category.all

def categories
  Category.all.map { |c| [ c.name, c.id ] }
end

并在浏览量中使用它

<%= select_tag(:category_id,
               options_for_select(categories), 
               include_blank: "Select Category") %>

你也可以尝试类似的方法。

products_controller.rb:

class ProductsController < ApplicationController
  before_action :set_select_collections, only: [:edit, :update, :new, :create]

  private
    def set_select_collections
      @categories = Category.all.map { |c| [ c.name, c.id ] }
    end
end

之后你应该可以使用:

_form.html.erb:

<%= select_tag(:category_id, options_for_select(@categories), include_blank: "Select one!") %>