Newbie - HABTM problems writing to Join Table in SQL


#1

I am attempting to document a join between two tables. There seems to be
no writing to my database. Please help me out it is driving me absolutly
crazy.

Basically i’ve got a table of directors that is called when the new/edit
controller model for films is activated. It shows the user a selectable
list of directors they can apply to films. The problem is in the
update/create part. I cannot figure out what to write to make it update
my directors_films database table.

Thanks so much for whomever braves this problem… I promise to return
the favor to another seeking knowledge someday!

-----schema.rb-----

ActiveRecord::Schema.define() do

create_table “directors”, :force => true do |t|
t.column “name”, :string, :default => “na”, :null => false
t.column “biography”, :text, :default => “”, :null => false
end

create_table “directors_films”, :id => false, :force => true do |t|
t.column “director_id”, :integer, :default => 0, :null => false
t.column “film_id”, :integer, :default => 0, :null => false
end

create_table “films”, :force => true do |t|
t.column “title”, :string, :default => “”, :null => false
t.column “release_date”, :date, :null => false
end

end

------director.rb-----

class Director < ActiveRecord::Base
has_and_belongs_to_many :films
end

------film.rb-------

class Film < ActiveRecord::Base
has_and_belongs_to_many :directors
end

--------application_helper.rb---------

module ApplicationHelper

def director_dropdown
select(:director, :id, Director.find(:all, :order => “name”).map {|d|
[d.name, d.director_id] })
end
end

--------films/form.rhtml-----------

Title
<%= text_field 'film', 'title' %>
Director
<%= director_dropdown %>

Release date
<%= date_select 'film', 'release_date', :order => [:day, :month, :year], :start_year => 1900 %>

--------films_controller----------

class FilmsController < ApplicationController
def index
list
render :action => ‘list’
end

GETs should be safe (see

http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }

def list
@film_pages, @films = paginate :films, :per_page => 10
end

def show
@film = Film.find(params[:id])
end

def new
@film = Film.new
@directors = Director.find_all
end

def create
@film = Film.new(params[:film])
if @film.save
flash[:notice] = ‘Film was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def edit
@film = Film.find(params[:id])
@directors = Director.find_all
end

def update
@film = Film.find(@params[:id])
if @film.update_attributes(params[:film])
flash[:notice] = ‘Film was successfully updated.’
redirect_to :action => ‘show’, :id => @film
else
render :action => ‘edit’
end
end

def destroy
Film.find(params[:id]).destroy
redirect_to :action => ‘list’
end
end


#2

def create
@film = Film.new(params[:film])

After this line you will (I think) want:

@film.directors = Director.find(params[:id])

you might need:

@film.directors = Director.find(params[:director][:id])

but I don’t think so.

if @film.save
  flash[:notice] = 'Film was successfully created.'
  redirect_to :action => 'list'
else
  render :action => 'new'
end

end


#3

I have tried similar to this, but have had no successes. What I get in
response is this:


ActiveRecord::RecordNotFound in Films#create

Couldn’t find Director without an ID
RAILS_ROOT: script/…/config/…

Application Trace | Framework Trace | Full Trace
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:939:in
find_from_ids' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.0/lib/active_record/base.rb:382:infind’
#{RAILS_ROOT}/app/controllers/films_controller.rb:26:in `create’
Request

Parameters: {“director”=>{“id”=>“1”}, “commit”=>“Create”,
“film”=>{“image_url”=>“na”, “crew”=>"", “title”=>"", “commentary”=>"",
“film_url”=>“na”, “release_date(1i)”=>“2006”, “video_url”=>“na”,
“release_date(2i)”=>“4”, “release_date(3i)”=>“5”, “distributor”=>“na”,
“cast”=>"", “synopsis”=>""}}

Show session dump

Response

Headers: {“cookie”=>[], “Cache-Control”=>“no-cache”}


Could you explain what this means?


#4

ActiveRecord::RecordNotFound in Films#create

Couldn’t find Director without an ID
RAILS_ROOT: script/…/config/…

Parameters: {“director”=>{“id”=>“1”}, “commit”=>“Create”,
“film”=>{“image_url”=>“na”, “crew”=>"", “title”=>"", “commentary”=>"",
“film_url”=>“na”, “release_date(1i)”=>“2006”, “video_url”=>“na”,
“release_date(2i)”=>“4”, “release_date(3i)”=>“5”, “distributor”=>“na”,
“cast”=>"", “synopsis”=>""}}

Show session dump

Response

Headers: {“cookie”=>[], “Cache-Control”=>“no-cache”}


Could you explain what this means?

The error, which I assume is on this line:

@film.directors = Director.find(params[:director][:id])

means that it’s trying to run find without having an :id parameter.

Which is odd because as you see from this:

Parameters: {“director”=>{“id”=>“1”}, “commit”=>“Create”,
“film”=>{“image_url”=>“na”, “crew”=>"", “title”=>"", “commentary”=>"",
“film_url”=>“na”, “release_date(1i)”=>“2006”, “video_url”=>“na”,
“release_date(2i)”=>“4”, “release_date(3i)”=>“5”, “distributor”=>“na”,
“cast”=>"", “synopsis”=>""}}

Specifically, the part

“director”=>{“id”=>“1”}

Indicates that the id should be accessible by [:director][:id]. I think.
:stuck_out_tongue:

You might try it again to make sure there were no small syntax mistakes.
In the mean time, anyone know what I’m missing? :slight_smile:

-Adam