Forum: Ruby on Rails newbie - HABTM problems writing to Join Table in SQL

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Fb8f512d95fa45e52f7cdd02e00d6c9f?d=identicon&s=25 Mason Kessinger (Guest)
on 2006-04-05 00:55
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-----------

<p><label for="film_title">Title</label><br/>
<%= text_field 'film', 'title'  %><br/>
Director<br/>
<%= director_dropdown %>
</p>

<p><label for="film_release_date">Release date</label><br/>
<%= date_select 'film', 'release_date', :order => [:day, :month, :year],
:start_year => 1900  %></p>

--------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
6ec1e89eef5ce09fbfa56be5b6dd17b5?d=identicon&s=25 Adam Bloom (admanb)
on 2006-04-05 06:59
>   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
Fb8f512d95fa45e52f7cdd02e00d6c9f?d=identicon&s=25 Mason Kessinger (Guest)
on 2006-04-05 15:14
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:in
`find'
#{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?
6ec1e89eef5ce09fbfa56be5b6dd17b5?d=identicon&s=25 Adam Bloom (admanb)
on 2006-04-05 18:25
> 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.
:P

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

-Adam
This topic is locked and can not be replied to.