Rails 4 рейк задача по обновлению записей. Найти по ts_code и обновить с помощью CSV

Немного грязный у меня здесь, пытаясь заставить это работать. У меня есть магазин с базой товаров. Мне дали CSV-файл с 3 столбцами и более 500 записей, ts_code cost_price и sell_price.

Поэтому мне нужна задача, которую я могу запустить, чтобы найти все продукты, которые соответствуют ts_code, а затем обновить cost_price и sell_price этих продуктов.

Я попытался отредактировать задачу, которую я использовал для импорта продуктов, как показано ниже.

Исходное задание

require 'csv'
desc "Imports a CSV file into an ActiveRecord table"
task :import, [:filename] => :environment do
CSV.foreach('csv/vow.csv', :headers => true) do |row|
Spree::Product.create!(row.to_hash)
end
end

Я надеялся, что что-то подобное сработает, но я застрял сейчас.

require 'csv'
desc "Imports a CSV file into an ActiveRecord table"
task :update, [:filename] => :environment do
CSV.foreach('csv/vow.csv', :headers => true) do |row|
a = Spree::Product.find_by(:ts_code)
Spree::Product.update_all!(a, row.to_hash)
end
end

Я также знаю, что мне нужно указать, какие столбцы нужно обновить, но я не уверен, где их разместить, например, cost & sell_price. Если бы кто-то мог помочь, это было бы здорово.

Все еще пытаясь заставить это работать как-то, следующее, что я попробовал, было это, но я получил ошибку неопределенного метода find_by. Синтаксис как-то не так, не уверен, насколько я близко.

require 'csv'
desc "Imports a CSV file into an ActiveRecord table"
task :update, [:filename] => :environment do
CSV.foreach('csv/recharge_pricing.csv', :headers => true) do |row|
product = find_by(ts_code: row["ts_code"]) || new
parameters = ActionController::Parameters.new(row.to_hash)
product.update(parameters.permit(:cost_price,:price))
product.save!
end
end

1 ответ

Решение

Ваш второй пример имеет правильный синтаксис find_by 1 - вам нужно вызвать его Spree::Product объект. Вы также можете позвонить Spree::Product.find_by_ts_code(row["ts_code"]) как ярлык.

Кроме того, вместо вашего || new синтаксис, вы можете посмотреть на find_or_create_by 2 - как то так:

product = Spree.Product.find_or_create_by(ts_code: row["ts_code"])

И, наконец, update звонки экономят для вас, так что ваши save! вызов избыточен.

Другие вопросы по тегам