Using after_save in block change class after_save_blocks array
Closed this issue · 5 comments
I use cscv-importer in conroller:
import = Importers::ImportMemberCSV.new(file: params[:import_file]) do
after_save { |member| list.subscribe(member) }
end
import.run!
Nonetheless I use after_save in block, it adds proc into Importers::ImportMemberCSV.config.after_save_blocks array
class Importers::ImportMemberCSV
include CSVImporter
model Member
column :email, to: ->(email) { email.downcase }, required: true
column :first_name
column :last_name
column :ip
when_invalid :skip
end
Hello @ysynesis,
Can you confirm that the issue you're running into is that the after_save
block you define for one instance of ImportMemberCSV
is being added to the class instead of the instance?
class MyImport
# ...
end
MyImport.new(file: file) do
after_save { puts "Hi!" }
end
import.run!
# => "Hi!"
MyImport.new(file: file).run!
# expected: ""
# actual: "Hi!"
OK, I'll look into this when I get a chance. As usual, any pull request is
greatly appreciated. 😉
On Sep 2, 2016 18:54, "ysynesis" notifications@github.com wrote:
@pcreux https://github.com/pcreux yes, exactly
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#44 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACw8x4Hm54oE0GeEUkqlXbQZrkh44QIks5qmFTUgaJpZM4JiVBx
.
Hi, I'm having the same issue.
The problem is here:
CsvImporter
def initialize(*args, &block)
@csv = CSVReader.new(*args)
@config = self.class.config.dup
the #dup call does a shallow copy so it doesn't copy a new Array for after_save and after_build blocks.
Thanks for your work, it's a very useful gem.
I have a improvement suggestion. Id like to add a 3rd option to this case where the block passed uses the column_definition too. This allows to do custom conversion with metadata stored in the column name. For example the columns header is defined as "name, birthdate[MM/DD/YY], address". So the column name matches trough a regex and you can capture the metadata inside []
case to_proc.arity
when 1 # to: ->(email) { email.downcase }
model.public_send("#{column_definition.name}=", to_proc.call(csv_value))
when 2 # to: ->(published, post) { post.published_at = Time.now if published == "true" }
to_proc.call(csv_value, model)
else
raise ArgumentError, "`to` proc can only have 1 or 2 arguments"
What do you think?
Issue was fixed in 0.3.2
. I still have to think about the "3rd option" to capture metadata inside header.