How to test if carrierwave file changed?

2019-04-29 20:50发布

问题:

I'm trying to test if a image was changed with carrier wave on my code, but I can't find a way to do this. It seems that the object is marked as changed even if the file is invalid, and thus it was not really changed.

Look the following output:

(rdb:1) job.translated_xliff
#<XliffUploader:0xcd8b380 ...>
(rdb:1) job.changed?
false # As expected, didn't changed yet
(rdb:1) job.translated_xliff = "foo"
"foo"
(rdb:1) job.changed?
true # Changed? "foo" is not a valid file. Lets see the file again...
(rdb:1) job.translated_xliff
#<XliffUploader:0xcd8b380 ...> # same object ID!

How can I check if this object was really changed on my code?

EDIT: I opened an issue on github, but the problem still not solved, yet more information can be found there

回答1:

Internally Carrierwave define(override) the ActiveRecord getter/setter on uploader column (translated_xliff)

Now every time one call the setter method job.translated_xliff = 'foo' (as mention by Bensie) it uses ActiveRecord::Dirty _will_change! method to notify the object it changing

followed by CarrierWave caching the supplied file

Here yours scenario

    job.translated_xliff
    => uploader 

    job.changed?
    => false

    job.translated_xliff = "foo"

    ## Now your trying to change the object so will_change! notify that 
    ##'translated_xliff' is changing after which Carrierwave try to cache the given 'file'(foo)

Now here the problem just before Carriewave start caching the file it perform a basic check like this

  new_file = CarrierWave::SanitizedFile.new(new_file)
  unless new_file.empty?
     ## Then  do caching 
  end  

empty? is use to determine is supplied value (in your case it foo) is a Path or File and it neither of two in your case and hence the file is never cache but the object is marked as changed

and hence you get this

job.changed?
=> true 

Now as a result while calling the job.translated_xliff method it pull the file from the store since the supplied value was never cached , you can see it working over here

Hence I mention in the comment If you want to achieve something of that kind perhaps you can check against the identifier and decide whether it changed

job.translated_xliff.identifier == "foo"

Just a suggestion though :)

Hope this help