Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

carrierwave: mount uploader on serialized dynamic attribute

first of all, i am using rails 3.1.3 and carrierwave from the master branch of the github repo.

i use a after_init hook to determine fields based on an attribute of the page model instance and define attribute accessors for these field which store the values in a serialized hash (hope it's clear what i am talking about). here is a stripped down version of what i am doing:

class Page < ActiveRecord::Base 
  serialize :fields, Hash 

  after_initialize :set_accessors 

  def set_accessors 
    case self.template 
      when 'standard' 
        class << self 
            define_method 'image' do 
              self.fields['image'] 
            end 
            define_method 'image=' do |value| 
              self.fields['image'] = value 
            end 
          end 
          mount_uploader :image,   PageImageUploader 
        end 
    end 
  end 
end 

leaving out the mount_uploader command gives me access to the attribute as i want. but when i mount the uploader a get an error message saying 'undefined method new for nil class'

i read in the source that there are the methods read_uploader and write_uploader in the extensions module. how do i have to override these to make the mount_uploader command work with my 'virtual' attribute.

i hope somebody has an idea how i can solve this problem. thanks a lot for your help.

best regard. dominik.

like image 412
domtra Avatar asked Jan 26 '12 10:01

domtra


1 Answers

Same problem but solved in your model you should override read_uploader(column) and write_uploader(column, identifier) instance methods. I also have a problem with #{column}_will_change! and #{column}_changed? for a virtual column so I had to define them too:

class A < ActiveRecord::Base
  serialize :meta, Hash

  mount_uploader :image, ImageUploader

  def image_will_change!
    meta_will_change!
    @image_changed = true
  end

  def image_changed?
    @image_changed
  end

  def write_uploader(column, identifier)
    self.meta[column.to_s] = identifier
  end

  def read_uploader(column)
    self.meta[column.to_s]
  end
end
like image 82
Antiarchitect Avatar answered Oct 15 '22 04:10

Antiarchitect