不在数据库中的CarrierWave属性总是等于nil

时间:2013-07-14 12:31:03

标签: ruby-on-rails carrierwave null

我使用CarrierWave gem的Rails 4.0.0。 为什么数据库中没有的属性总是等于nil? 它只在文件PostUploader中。最终,数据到来了。如何确保文件PostUploader中有这些属性?

class PostUploader < CarrierWave::Uploader::Base
...
  version :thumb do
    process :crop
  end

  def crop
    model.image_crop # => nil
  end
...
end

模型:

validates :name, presence: true
mount_uploader :image, PostUploader
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h

控制器:

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"}

PostUploader中的

模型对象:

Post id: nil, name: "trololo", image: nil, created_at: nil, updated_at: nil

model.crop_x && model.crop_w always => nil

https://github.com/CandyDandy/Realty/tree/development这个项目。

1 个答案:

答案 0 :(得分:7)

我认为(基于你的代码)的原因是分配在rails和carrierwave中串联工作的方式来详细解释请注意下面的例子

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就像这样

a1 = A.new("BAD","GOOD")
 => Abuse word isnt set yet ....
 => This will be nil => 
# But when you do this
a1.abuse_word
  => "BAD"

现在你可以想象这里发生类似这样的事情我的意思

考虑到这是你的哈希

{"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"}

不用担心image=(即uploader_column= setter属性被Carrierwave覆盖,crop内部调用您定义的处理器,即assign_attributes

现在如果您检查rails,rails会根据传递给它的哈希值image=[Value obtain from hash]检查here

现在当rails执行此操作时(通过解析你的参数)

crop这会调用由carrierave定义的方法,内部调用

处理器crop_x,因此您可以获得所需的结果crop_w&amp;&amp; nil始终设置为image=,因为导轨尚未完成crop_x的分配,尚未分配crop_wimage,因为在哈希上方在public_send("crop_x=",[desired_value])密钥

之后

所以

public_send("crop_w=",[desired_value]) processor

当您的代码到达crop以处理图像时,

尚未评估 在处理器nil中进行评估时,您的值为p1 = Post.new(post_params.except("image")) p1.image = post_params.delete("image") p1.save

解决方案:

我建议您在控制器中执行类似的操作

crop_x

或者(我不建议这样做)确保以某种方式确保crop_wimage在post_params哈希中的{"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">} 键之前,这样你的哈希看起来像这样< / p>

{{1}}

您可以清楚地识别两者之间的区别

希望这个帮助