【问题标题】:Rails 4 how to call accessible_attributes from ModelRails 4如何从模型中调用accessible_attributes
【发布时间】:2013-12-31 08:37:13
【问题描述】:

您好,我正在尝试这个 tuto on Rails 演员 (Importing csv Excel file)。我在这条线上有一个错误product.attributes = row.to_hash.slice(*accessible_attributes)

undefined local variable or methodaccessible_attributes' 用于#`

这是我的模型。

class Product < ActiveRecord::Base
  require 'roo'
  validates_presence_of :price
  #attr_accessible :name, :price, :released_on #I removed this line (rails 4)


  def self.to_csv(options = {})
    CSV.generate(options) do |csv|
      csv << column_names
      all.each do |product|
        csv << product.attributes.values_at(*column_names)
      end
    end
  end

  def self.import(file)
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      product = find_by_id(row["id"]) || new
      product.attributes = row.to_hash.slice(*accessible_attributes)
      product.save!
    end
  end

  def self.open_spreadsheet(file)
    case File.extname(file.original_filename)
    when ".csv" then Roo::Csv.new(file.path)
    when ".xls" then Roo::Csv.new(file.path)
    when ".xlsx" then Roo::Csv.new(file.path)
    else raise "Unknown file type: #{file.original_filename}"
    end
  end
end

在我的控制器上结束,我定义了 product_params

def product_params
    params.require(:product).permit(:name, :price, :released_on)
  end

我尝试导入的 csv 如下所示:

id,name,realased_on,price,created_at,updated_at
1,Acoustic Guitar,2012-10-03,3456.54,2013-12-09 00:00:23 UTC, 2012-12-08 23:45:46 UTC

【问题讨论】:

  • undefined local variable or method accessible_attributes' for #<0x000000042b3640>

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

在 Rails 4.1 下处理此 Railscast 时,我通过将 access_attributes 替换为 row.to_hash.keys 来获得该方法。

def self.import(file)
   spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      product = find_by_id(row["id"]) || new
      product.attributes = row.to_hash.slice(*row.to_hash.keys)
      product.save!
    end
end

【讨论】:

  • 这与product.attributes = row.to_hash 相同,因为您从row 对象中获取所有密钥。它会起作用,但 Railscast 代码的目的是仅从行中获取与 Product 模型中具有匹配属性的列。 (通常电子表格的列数比模型中需要的多。)由于 Rails 4 不使用 attr_accessible,因此您必须按照上面接受的答案明确命名所需的键。
  • 你有什么改变不上传ID只是继续序列?
【解决方案2】:

实际上accessible_attributes 获取那些在模型中声明attr_accessible 但在rails 4 中他们已从模型中删除attr_accessible 并使用strong_parameter 代替的列,因此为此制作了一个同名的方法accessible_attributes在他的模型中,然后在该方法中声明您想要的列数组。如:

def accessible_attributes
 [col1_name, col2_name, ....]
end

【讨论】:

  • Are you you is [col1_name, col2_name] 我将其更改为 [:name,:lastname] 但不起作用
  • 非常感谢任何帮助
  • 在 Rails 5 中,我添加了“self”。到方法定义,并将名称作为字符串传递def self.accessible_attributes ['col1_name', 'col2_name', '...'] end
【解决方案3】:

按原样使用公认的解决方案对我来说并不奏效。我需要添加“自我”。到方法定义以使其工作。

另一种方式,如果您调用accessible_attributes 的唯一位置在self.import 中,则将您要查找的字段定义为本地数组变量。

def self.import(file)
    accessible_attributes = ['my_attribute_name1','my_attribute_name2', '...']
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      cae = find_by_id(row["id"]) || new
      cae.attributes = row.to_hash.slice(*accessible_attributes)
      cae.save!
   end
end

【讨论】:

    【解决方案4】:

    回答上一个问题,为什么验证消息显示“价格不能为空白”。我认为这可能是由于数据在 Excel 中保存为通用格式。我遇到了类似的问题,将其更改为文本格式后错误消息消失了。我不知道原因,但试一试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 2010-09-28
      • 2016-01-28
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      相关资源
      最近更新 更多