I am use Rails 4.0.0 with CarrierWave gem. Why are the attributes that are not in the database is always equal to nil? It is only within the file PostUploader. Ultimately, the data arrives. How to make sure that these attributes are available in the file PostUploader?
class PostUploader < CarrierWave::Uploader::Base
...
version :thumb do
process :crop
end
def crop
model.image_crop # => nil
end
...
end
model:
validates :name, presence: true
mount_uploader :image, PostUploader
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
controller:
def create
@post = Post.new(post_params)
...
end
def post_params
params.require(:post).permit(:name, :image, :crop_x, :crop_y, :crop_w, :crop_h)
end
post_params
{"name"=>"trololo", "image"=>#, @original_filename="large (3).jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"large (3).jpg\"\r\nContent-Type: image/jpeg\r\n">, "crop_x"=>"0", "crop_y"=>"0", "crop_w"=>"100", "crop_h"=>"200"}
model object in PostUploader:
Post id: nil, name: "trololo", image: nil, created_at: nil, updated_at: nil
and
model.crop_x && model.crop_w always => nil
https://github.com/CandyDandy/Realty/tree/development This project.
I think the reason(based upon your code ) for that is the way assignment are working in tandem inside rails and carrierwave to explain in detail please observe the example below
class A
attr_accessor :abuse_word,:word
def initialize(abuse_word,word)
self.word = word
self.abuse_word = abuse_word
end
def word=(word)
puts "Abuse word isnt set yet ...."
puts "This will be nil => #{self.abuse_word}"
@word = word
end
end
O/p for the program is Like this
a1 = A.new("BAD","GOOD")
=> Abuse word isnt set yet ....
=> This will be nil =>
# But when you do this
a1.abuse_word
=> "BAD"
Now you can imagine something like this happening internally here what I meant
Considering this is your hash
{"name"=>"trololo", "image"=>#, @original_filename="large (3).jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"large (3).jpg\"\r\nContent-Type: image/jpeg\r\n">, "crop_x"=>"0", "crop_y"=>"0", "crop_w"=>"100", "crop_h"=>"200"}
No mind you image=
(i.e your uploader_column=
setter attributes is overridden by Carrierwave
which internally call the processor which you have define i.e crop
)
Now If you check the rails,rails does an assign_attributes
based upon the hash passed to it check over here
Now when rails does this (by parsing your params)
image=[Value obtain from hash]
this invoke the method define by carrierave which internally call the
processor crop
and hence you get the desired result as crop_x
&& crop_w
always set to nil
because the rails hasn't finish with the assignment of image=
and is yet to assign crop_x
and crop_w
because in hash above they are after in the image
key
So
public_send("crop_x=",[desired_value])
public_send("crop_w=",[desired_value])
is not been evaluate yet when your code reached to processor
to process the image hence
when evaluating in processor crop
you get there value as nil
I suggest you do something like this in your controller
p1 = Post.new(post_params.except("image"))
p1.image = post_params.delete("image")
p1.save
Or else(I wont suggest this) make sure somehow make sure the crop_x
,crop_w
are prior to image
key in the post_params hash so your hash would look something like this
{"name"=>"trololo","crop_x"=>"0", "crop_y"=>"0", "crop_w"=>"100", "crop_h"=>"200", "image"=>#, @original_filename="large (3).jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"large (3).jpg\"\r\nContent-Type: image/jpeg\r\n">}
You can clearly identify the difference between the two
Hope this help
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With