How to set a relationship with a value from a selection list


#1

I realize this is probably a very basic problem but I’m developing my
first rails app and running into this problem.

I’m trying to write a photoblog application. I have a photo table and an
album table. Photo has a to-one relationship to Album. Photo.album_id =>
Album.id

In my view for photo I have a selection list that’s populated with all
the available albums.
<%= select(“post”, “album_id”, Album.find_all.collect {|a| [a.name,
a.id]}, {:include_blank => true}) %>

This work in so much as I can see the albums being listed in the
selection list.

Then in my photo_controller I’m trying to set the relationship when the
photo is saved in a method called ‘create’

def create
@photo = Photo.new(params[:photo])
@photo_file = PhotoFile.new(params[:photo_file])
@photo.photo_file = @photo_file
@photo.album = @post.album_id
@photo.blog_user_id = 1
if @photo.save!
flash[:notice] = ‘Photo was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

When I click save I get the following error…

NoMethodError in Photo#create

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.album_id

I’ve looked through this forum and read numerous similar problems, and
from what I can tell I’m doing the right thing. Can someone tell me
where I’m being thick.

-Matt


#2

On Thu, Feb 23, 2006 at 02:28:22PM +0100, Matthew Oliver wrote:

I’m trying to write a photoblog application. I have a photo table and an
album table. Photo has a to-one relationship to Album. Photo.album_id =>
Album.id

In my view for photo I have a selection list that’s populated with all
the available albums.
<%= select(“post”, “album_id”, Album.find_all.collect {|a| [a.name,
a.id]}, {:include_blank => true}) %>

s/post/photo/

@photo.album = @post.album_id
Remove this line because the hash params[:photo] will contain
the album_id.

@photo.blog_user_id = 1
if @photo.save!
flash[:notice] = ‘Photo was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

FWIW I’m new to rails so I could easily be way wrong with my
suggestion. :slight_smile:

-steve


#3

@photo.album = @post.album_id
Remove this line because the hash params[:photo] will contain
the album_id.

@photo.blog_user_id = 1
if @photo.save!
flash[:notice] = ‘Photo was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

FWIW I’m new to rails so I could easily be way wrong with my
suggestion. :slight_smile:

-steve

Hi Steve

If I simply remove that line I get a forien key restraint error.

Mysql::Error: #23000Cannot add or update a child row: a foreign key
constraint fails (photoblog_development/photos, CONSTRAINT
photos_ibfk_1 FOREIGN KEY (album_id) REFERENCES albums (id)):
INSERT INTO photos (lens, mounting, title, album_id,
photo_description, camera, iso, shutter, blog_user_id,
camera_mode, added_on, shot_on, aperture, flash) VALUES(’’,
‘’, ‘’, 0, ‘’, ‘’, ‘’, ‘’, 1, ‘’, NULL, NULL, ‘’, ‘’)

How do I go about setting this relationship?


#4

On Thursday, February 23, 2006, at 3:14 PM, Andrew Otwell wrote:

@photo.album = @post.album_id

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.album_id

You use @post, but it’s not defined anywhere. That looks like what’s
causing the nomethod error.

Whoops, I meant to write: “That looks like what’s causing the nil
object
error.”


#5

Andrew Otwell wrote:

On Thursday, February 23, 2006, at 3:14 PM, Andrew Otwell wrote:

@photo.album = @post.album_id

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.album_id

You use @post, but it’s not defined anywhere. That looks like what’s
causing the nomethod error.

Whoops, I meant to write: “That looks like what’s causing the nil
object
error.”

Ahhhh I see…
So using the variable name post in the select statement isn’t enough?

<%= select(“post”, “album_id”, Album.find_all.collect {|a| [a.name,
a.id]}, {:include_blank => true}) %>

I thought calling it post here would mean I could reference in my
controllor as such. I’m still lost as to what I should do? When I try to
save the new photo I get an exception page that shows me the information
from the request… in that information I see the album
“post”=>{“album_id”=>“1”}} and it’s pointing at the correct id and
everything I just don’t know how to reference that request object in my
controllor to set the relationship!?! frustrating!


#6

@photo.album = @post.album_id

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.album_id

You use @post, but it’s not defined anywhere. That looks like what’s
causing the nomethod error.


#7

On Thu, Feb 23, 2006 at 04:04:33PM +0100, Matthew Oliver wrote:

How do I go about setting this relationship?

You need to remove the line mentioned as well as make the other
change (post -> photo) in the call to the select method in your
view. If you don’t then the album_id doesn’t get stuffed in the
params[:photo] hash which is what is causing the error above.

As it originally stood the album_id could only be obtained using
params[:post][:album_id]. Putting it in the photo attributes hash
means it is supplied to Photo.new in the following line of your
code:

@photo = Photo.new(params[:photo])

This mitigates the need to later have to resort to this:

@photo.album_id = params[:post][:album_id];

-steve


#8

Awesome! It worked!
Thank you so much Steve.

-M