【问题标题】:Error (private method `select' called for nil:NilClass):错误(调用 nil:NilClass 的私有方法“选择”):
【发布时间】:2019-03-11 02:41:53
【问题描述】:

为什么会出现此错误?我该如何解决?

ActionView::Template::Error(调用私有方法 `select' nil:NilClass):

class MyformObject

  include ActiveModel::Model

  #validations


@form_structure =
  [
    {  name: :country, model: :car, field_type: :string },
    {  name: :street, model: :repair_center, field_type: :string }
  ]

  def get_model_from_name(name)
    model = @form_structure.select { |record| record[:name] == name }.first[:model]
  end  

  def type_for_attribute(name)
    get_model_from_name(name).to_s.capitalize.constantize.type_for_attribute
  end 

  def has_attribute?(name)
    get_model_from_name(name).to_s.capitalize.constantize.attributes.key?(name.to_s)
   end

def self.fields_of_model(model)
  form_structure.select { |record| record[:model] == model }.map { |record| record[:name] }
end

 end

更新版本:

错误:nil:NilClass def 的未定义方法“[]” get_model_from_name(名称)
模型 = self.class.form_structure.select { |记录|记录[:name] == name }.first[:model] 结束

class MyformObject

  include ActiveModel::Model

  #validations


def self.form_structure 
  [
    {  name: :country, model: :car, field_type: :string },
    {  name: :street, model: :repair_center, field_type: :string }
  ]
end

  def get_model_from_name(name)
    model = self.class.form_structure.select { |record| record[:name] == name }.first[:model]
  end  

  def type_for_attribute(name)
    get_model_from_name(name).to_s.capitalize.constantize.type_for_attribute
  end 

  def has_attribute?(name)
    get_model_from_name(name).to_s.capitalize.constantize.attributes.key?(name.to_s)
   end

def self.fields_of_model(model)
  form_structure.select { |record| record[:model] == model }.map { |record| record[:name] }
end

def self.delegate_fields_to(*models)
      models.each do |model|
        fields_of_model(model).each do |attr|
          delegate attr.to_sym, "#{attr}=".to_sym, to: model
        end
      end
    end

 end

【问题讨论】:

  • 您的 @form_structure 变量现在无法从您的 MyFormObject 实例方法访问,这就是为什么在调用它时它返回 nil。如果内容始终是“常量”,您可以使用“常量”,否则您可以创建一个返回该内容的方法。还有其他类型的变量可以从任何实例方法访问,但不鼓励使用它们。
  • 所以你建议使用常量?我还有哪些其他选择?

标签: ruby-on-rails ruby ruby-on-rails-5.2


【解决方案1】:

恕我直言,常量是处理该数组的好方法,因为它充满了硬编码值,并且它只包含两个元素。

所以你可以这样做:

class MyformObject
  FORM_STRUCTURE = [
    { name: :country, model: :car, field_type: :string },
    { nname: :street, model: :repair_center, field_type: :string }
  ].freeze
  private_constant :FORM_STRUCTURE

  def get_model_from_name(name)
    FORM_STRUCTURE.select { |record| record[:name] == name }.first[:name]
  end 
end

p MyformObject.new.get_model_from_name(:country)
# [:country]

你可以看到这个常量不能被修改,只能在 MyformObject 范围内使用。

我删除了模型局部变量赋值,因为它没有被使用。

【讨论】:

  • 知道为什么 `has_attribute?(name)` 会出现未定义的方法 `attributes' 错误吗?
  • 我需要更多信息来尝试回答这个问题。
  • 你需要知道什么?
  • 你得到的整个错误和涉及的代码。
  • 如果您添加了self,那么当您从任何地方调用它时,请尝试使用MyformObject.form_structure
【解决方案2】:

你可以试试这样,执行起来有点容易,

  def get_model_from_name(name)
    model = form_structure.select { |record| record[:name] == name }.first[:model]
  end

  def form_structure
    [
      {  name: :country, model: :car, field_type: :string },
      {  name: :street, model: :repair_center, field_type: :string }
    ]
  end

为了更好地封装,您可以将方法form_structure 放在私有范围内。

【讨论】:

  • 我喜欢这个,但得到undefined local variable or method form_structure for MyformObject 不知道为什么
  • 我无法理解它是如何引发错误的,因为我们在它下面添加了form_structure 方法。
  • 我上面定义的,有关系吗?
  • 不,没关系。它应该作为实例方法包含在类中,并且可以在没有这种中断的情况下工作。
  • 这是什么原因造成的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 2017-02-26
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多