Displaying images in Ruby

I’m trying to show an image that is associated with a house. It’s
crashing on the houses that do not have images associated with them.
Here’s my code:

<% if @house.picture_id != nil %>

Image Goes Here

Upload: <%= file_field(“picture”, “picture”) %>
<% else %>
<%= image_tag(url_for(
:controller => “picture_admin”,
:action => “show”,
:id => @picture.id),
:alt => @picture.name,
:class => “admin-img-preview”) %>
<% end %>

I’ve also tried the following:

<% if !@house.picture %>
<% if @house.picture_id.nil? %>
<% if @house.picture_id != 0 %>

I’m out of ideas! Please tell me how I can show this for houses that do
not have images. Thanks!

file_field (like text_field, check_box) and so on assume that its first
parameter is the name of a instance variable and the second the name of
a method that can be called on that instance variable.

So here file_field will try to do @picture.picture, which i’m assuming
fails because @picture is nil.
You probably want something like file_field(“house”, picture) (or
possibly you just want to use file_field_tag)

Fred

Frederick C. wrote:

file_field (like text_field, check_box) and so on assume that its first
parameter is the name of a instance variable and the second the name of
a method that can be called on that instance variable.

So here file_field will try to do @picture.picture, which i’m assuming
fails because @picture is nil.
You probably want something like file_field(“house”, picture) (or
possibly you just want to use file_field_tag)

Fred

Ok, thanks. I’ll try that this evening. Just for more information, I
have a PICTURES table and a HOUSES table. The HOUSES table has a
foreign key of “picture_id” to the pictures table. When I’m saving the
fields for a new house, I’m using the file_field to browse for an image.
Then, in the “create” method in my house_controller I’m using:

@house = House.new(params[:house])
@picture = Picture.new(params[:picture])
if @picture.save
@house.picture_id = @picture.id
end
#…
#continue with @house processing…

Everything works fine, except when I try to call “/house/edit/1” when
the house entry for id of 1 does not have a picture with it. So I
thought by using “@house.picture_id” I could check that field to see if
it was empty, and if it was, display the “file_field” again. Does your
reply still apply now that you know how I’m doing things? Is there a
way to check for a null “picture_id” field, and show a file_field to
upload an image if so? Thanks!

Also, I’m using “has_one” and “belongs_to” as my model relationships
between HOUSES and PICTURES, just so you know. Thanks.

First of all, I was reading a little hastily this morning, and actually
file_field is a little different to the other blah_field helpers - the
others use the parameters to get the current value of the attribute as
their default, which file_field doesn’t, so file_field(“picture”,
“picture”) shouldn’t really care about the actual value of @picture

Yes, you can use house.picture_id or house.picture to tell if a house
does or does not have a picture; however given that you then go on to
use @picture, the most intuitive thing for me would be <% if @picture %>

What would really be helpful too, is the exact error that you get on the
page.

Fred

Frederick C. wrote:

First of all, I was reading a little hastily this morning, and actually
file_field is a little different to the other blah_field helpers - the
others use the parameters to get the current value of the attribute as
their default, which file_field doesn’t, so file_field(“picture”,
“picture”) shouldn’t really care about the actual value of @picture

Yes, you can use house.picture_id or house.picture to tell if a house
does or does not have a picture; however given that you then go on to
use @picture, the most intuitive thing for me would be <% if @picture %>

What would really be helpful too, is the exact error that you get on the
page.

Fred

Ok, thanks. I’ll post the exact error when I get home from work this
evening.

Ok, here’s the error I get:

Couldn’t find Picture without an ID

RAILS_ROOT: ./script/…/config/…
Application Trace | Framework Trace | Full Trace

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:939:in
find_from_ids' c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:382:infind’
#{RAILS_ROOT}/app/controllers/house_admin_controller.rb:51:in edit' -e:4:inload’
-e:4

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:939:in
find_from_ids' c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:382:infind’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in
send' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:inperform_action_without_filters’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in
perform_action_without_benchmark' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:inperform_action_without_rescue’
c:/ruby/lib/ruby/1.8/benchmark.rb:293:in measure' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:inperform_action_without_rescue’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in
perform_action' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:insend’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in
process_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:inprocess_without_session_management_support’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in
process' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:indispatch’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:115:in
handle_dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:81:inservice’
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:in service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:inrun’
c:/ruby/lib/ruby/1.8/webrick/server.rb:173:in start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:162:instart’
c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in start_thread' c:/ruby/lib/ruby/1.8/webrick/server.rb:95:instart’
c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in each' c:/ruby/lib/ruby/1.8/webrick/server.rb:92:instart’
c:/ruby/lib/ruby/1.8/webrick/server.rb:23:in start' c:/ruby/lib/ruby/1.8/webrick/server.rb:82:instart’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:67:in
dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/servers/webrick.rb:59 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:ingem_original_require’
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:inrequire’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/server.rb:30
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
gem_original_require' c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:inrequire’
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in
`require’
script/server:3

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:939:in
find_from_ids' c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:382:infind’
#{RAILS_ROOT}/app/controllers/house_admin_controller.rb:51:in edit' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:insend’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in
perform_action_without_filters' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:inperform_action_without_benchmark’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in
perform_action_without_rescue' c:/ruby/lib/ruby/1.8/benchmark.rb:293:inmeasure’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in
perform_action_without_rescue' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:inperform_action’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in
send' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:inprocess_without_filters’
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in
process_without_session_management_support' c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:inprocess’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in
dispatch' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:115:inhandle_dispatch’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:81:in
service' c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:104:inservice’
c:/ruby/lib/ruby/1.8/webrick/httpserver.rb:65:in run' c:/ruby/lib/ruby/1.8/webrick/server.rb:173:instart_thread’
c:/ruby/lib/ruby/1.8/webrick/server.rb:162:in start' c:/ruby/lib/ruby/1.8/webrick/server.rb:162:instart_thread’
c:/ruby/lib/ruby/1.8/webrick/server.rb:95:in start' c:/ruby/lib/ruby/1.8/webrick/server.rb:92:ineach’
c:/ruby/lib/ruby/1.8/webrick/server.rb:92:in start' c:/ruby/lib/ruby/1.8/webrick/server.rb:23:instart’
c:/ruby/lib/ruby/1.8/webrick/server.rb:82:in start' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/webrick_server.rb:67:indispatch’
c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/servers/webrick.rb:59
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
gem_original_require' c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:inrequire’
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in
require' c:/ruby/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/commands/server.rb:30 c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:ingem_original_require’
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
require' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:inrequire’
script/server:3
-e:4:in `load’
-e:4

Request

Parameters: {“id”=>“7”}

The “id” => “7” corresponds to the url /house_admin/edit/7 (which is the
ID for the house entry). Hopefully you can help! Thanks!

ryan wrote:

I fixed it… thanks for the efforts anyway!

Can you give the resolution?

I fixed it… thanks for the efforts anyway!

Ma Lijun wrote:

ryan wrote:

I fixed it… thanks for the efforts anyway!

Can you give the resolution?

It was ignorance on my part for not checking for the @house.picture_id
in the controller BEFORE attempting to setup the @picture object. So
this is what I did:

if @house.picture_id != nil
@picture = Picture.find(@house.picture_id)
end

That worked like a charm. Thanks for all the help. However, if you
don’t mind, can you help me with another problem? I was debating saving
to the database vs. a filesystem, and was trying to get the filesystem
to work by doing this:

@house = House.new(params[:house])
@filename = @params[:picture][:picture].original_filename
File.open("#{RAILS_ROOT}/public/images/#{@filename}", “wb”) do |f|
f.write(@params[:picture][:picture].read)
end

That works, but it writes a “0kb” file to the directory. How can I get
it to actually put the file data there??? Thanks for any advice.

ryan wrote:

      :action => "show",

I’m out of ideas! Please tell me how I can show this for houses that do
not have images. Thanks!


Posted via http://www.ruby-forum.com/.

If I read your code correctly, it looks like you want to trap @houses
without pictures in the first part of your conditional.

Try this…
<% unless @house.picture_id %>
do stuff for houses without pictures
<% else %>
do stuff for houses with pictures
<% end %>

_Kevin

I use a similar piece of code that checks for the existence of an image
filename. My if statement translated into your code would look like:

<% if @house.picture_id? %>

I have a picture id!


<% else %>

Darn it - no picture id, better place a generic image
here…

I hope this helps,

Paul

ryan wrote:

Ma Lijun wrote:

ryan wrote:

I fixed it… thanks for the efforts anyway!

Can you give the resolution?

It was ignorance on my part for not checking for the @house.picture_id
in the controller BEFORE attempting to setup the @picture object. So
this is what I did:

if @house.picture_id != nil
@picture = Picture.find(@house.picture_id)
end

That worked like a charm. Thanks for all the help. However, if you
don’t mind, can you help me with another problem? I was debating saving
to the database vs. a filesystem, and was trying to get the filesystem
to work by doing this:

@house = House.new(params[:house])
@filename = @params[:picture][:picture].original_filename
File.open(“#{RAILS_ROOT}/public/images/#{@filename}”, “wb”) do |f|
f.write(@params[:picture][:picture].read)
end

That works, but it writes a “0kb” file to the directory. How can I get
it to actually put the file data there??? Thanks for any advice.

I highly recommend the FlexImage plugin for this, and not just because I
wrote it.

http://beautifulpixel.com/flex_image/index.html

With FlexImage in charge of your Picture model, you can have it read and
write the binary data either to the database or to disk or the very
easily. Uploads and binary data storage are all handled for you without
any complicated code.