Атрибуты CarrierWave, которых нет в базе данных, всегда равны нулю

Я использую Rails 4.0.0 с драгоценным камнем CarrierWave. Почему атрибуты, которых нет в базе данных, всегда равны нулю? Это только внутри файла 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 Этот проект.


person Sterjakov    schedule 14.07.2013    source источник


Ответы (1)


Я думаю, что причина (на основе вашего кода) заключается в том, что назначение работает в тандеме внутри рельсов и несущей волны, чтобы подробно объяснить, пожалуйста, обратите внимание на пример ниже.

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= переопределяются Carrierwave, которые внутренне вызывают процессор, который вы определили, т.е. crop)

Теперь, если вы проверяете рельсы, рельсы выполняют assign_attributes на основе переданного ему хэша, проверяют здесь

Теперь, когда рельсы делают это (путем разбора ваших параметров)

image=[Value obtain from hash] это вызывает метод, определенный оператором, который внутренне вызывает

процессор crop и, следовательно, вы получаете желаемый результат, так как crop_x && crop_w всегда устанавливается на nil, потому что рельсы еще не закончили с назначением image= и еще не назначили crop_x и crop_w, потому что в хэше выше они находятся после в ключе image

So

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_w предшествуют ключу image в хэше 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">}

Вы можете четко определить разницу между двумя

Надеюсь, это поможет

person Viren    schedule 19.07.2013
comment
Большое спасибо! Вы помогли мне. Теперь все работает. Вы мой спаситель! :)) - person Sterjakov; 19.07.2013
comment
Отличная идея. Изменение params — гораздо лучший способ указать атрибуты Carriewave. Вам не нужно иметь дело с методами attr или обратными вызовами. - person dhulihan; 20.06.2014