Simple ActiveRecord question.

I've programmed in ruby for awhile, but I'm just getting into AR. I can boil my current problem understanding it down to the following example.

Thanks,           Kyle

#!/usr/bin/ruby require 'rubygems' require 'active_record'

ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "foo.db")

ActiveRecord::Schema.define() do create_table :containers do |table|    table.column :name, :string end create_table :things do |table|    table.column :description, :string end end

class Container<ActiveRecord::Base has_many :things end

class Thing<ActiveRecord::Base belongs_to :container end

Container.create(:name=>"Bucket") bucket=Container.find_by_name("Bucket") pocket=Container.create(:name=>"Pocket")

bucket.save pocket.save

Container.find(:all) #this will find both containers

Thing.find(:all) #empty, as expected

bucket.things.create(:description=>"fish") pocket.things.create(:description=>"lint")

Thing.find(:all) #looks good...

#but how come pocket.things.find(:all) #throws some huge error (below) instead of finding the things in the pocket?

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: things.container_id: SELECT * FROM things WHERE (things.container_id = 2)         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/connection_adapters/abstract_adapter.rb:128:in `log'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/connection_adapters/sqlite_adapter.rb:145:in `execute'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/connection_adapters/sqlite_adapter.rb:346:in `catch_schema_changes'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/connection_adapters/sqlite_adapter.rb:145:in `execute'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/connection_adapters/sqlite_adapter.rb:165:in `select_all'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/base.rb:427:in `find_by_sql'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/base.rb:997:in `find_every'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/base.rb:418:in `find'         from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/ active_record/associations/has_many_association.rb:91:in `find'         from (irb):68

create_table :things do |table|    table.column :description, :string

You need a container_id field here.

class Thing<ActiveRecord::Base belongs_to :container

belongs_to requires a foreign key.

This is not enough: you do actually need to create the container_id column on the things table.

Fred

The "find all" is automatic. You can just magically use the pocket.things array without having to prepare it. And if you have a Thing and you want to associate it with a Pocket, all you have to do is pocket.things << thing and AR will update thing and save it.

I was too hasty in my reply. Listen to what Greg said :slight_smile:

Fred, Greg, thanks so much. Just that simple addition made it behave the way I thought it should :slight_smile:

create_table :things do |table|    table.column :description, :string    table.column :container_id, :int end

George, now that I've got that line, it does indeed work like I'd hoped. Sweet.

So, now the next question, how would I find a container by it's contents?

Container.find_by_name("Pocket") #seems easy enough, but I can't do.... Container.find_by_thing #OK Container.column_names only has id and name, so I can make an easy guess why _that_ didn't work.. #but how would you get something like finding Containers by things to work? Or is the solution really just to #search the Thing class for container_id?

Thanks all --Kyle