ActiveRecord does not load attributes


#1

Hello everybody!

So this is likely a complete n00bish question as I only started riding
the rails last Wednesday, but I have been tearing my hair out over
this one for a number of hours now.

I created a model/table Picture/pictures and followed the guide at
http://manuals.rubyonrails.com/read/chapter/57 for uploading the file.
I have a field “path” which is to be the location relative to “public”
of the picture. The idea is that the filename is taken from what is
originally uploaded (in my case, ‘dog.png’). The database is
successfully updated with the path, but whenever I try:

script/runner ‘puts Picture.find_by_id(34).path’

I just get nil. I know that it works otherwise, since switching out
path for name (another one of the saved fields) works just fine.

Here are some snippets of my code:

picture.rb

def file=(incoming_file)
@temp_file = incoming_file
@filename = sanitize_filename incoming_file.original_filename
@content_type = incoming_file.content_type
@path = ‘/pictures/’ + @filename
end

before_save :set_path

attr_reader :filename
attr_accessor :path

def after_save
if @temp_file
File.open(‘public/’ + @path, “wb”) { |f|
f.write(@temp_file.read) }
end
end

def before_destroy
# delete the file from the filesystem
File.delete [‘public’,self.path]
end

private

def sanitize_filename(file_name)
# get only the filename, not the whole path (from IE)
just_filename = File.basename(file_name)
# replace all non-alphanumeric, underscore or periods with
underscores
just_filename.gsub(/[^\w.-]/,’_’)
end

def set_path
self.path = ‘pictures/dog.png’
end

END

Thanks in advance for any help and thank you for such an amazing
framework!

Daniel H.


#2

Well, you didn’t tell whether your database table contains field ‘path’.

If it does, then attr_accessor shoudn’t be there and you should not
assign value to instance variable. You are clobbering Rails auto-
magic with this.

If it doesn’t, how do you think Rails could get it when model object
is instantiated? You need to store all model info in database fields,
or at least enough to restore complete attributes manually in
after_initialize.

In short, you should treat ‘path’ either as table field or not, and
not mix those two approaches.

izidor


#3

Daniel H. wrote:

picture.rb

attr_accessor :path

AR getter and setter methods are auto-created from the DB columns.
They are not just normal instance variable-backed attributes.
Your attr_ definitions will override the AR methods for accessing
these attributes.

Remove the attr_ definitions, and in the “file=” method replace
the "@"s with “self.” for each AR attribute being set.


We develop, watch us RoR, in numbers too big to ignore.


#4

wow, thanks for the quick replies! As you can see, I am still very new
at this whole Ruby thing.

Deleting the attr_reader and accessors made everything work quite
nicely. I am still trying to sort out the difference between variable,
:variable, @variable, and self.variable in my head.

Thanks once again,
Daniel H.