Search code examples
ruby-on-rails-3activerecordforeign-keysassociationshas-many

Rails 3 : Overriding rails convention to accommodate custom made FK and PK


I am trying to insert data into a Table B which refers to Table A using foreign key associations.
Here is my code.

models.rb

class StudentStatusReport < ActiveRecord::Base
attr_accessible :student_id, :mark
belongs_to :student_details, :class_name => "StudentDetails", :foreign_key => "student_id"
end

class StudentDetails < ActiveRecord::Base
attr_accessible :student_id, :name
has_many :student_status_reports
end  

and Migrations.rb are as follows

 class CreateStudentDetails < ActiveRecord::Migration
  def change
  create_table :student_details, {:id => false} do |t|
    t.string :student_id
    t.string :name
    t.timestamps
  end
  execute "ALTER TABLE student_details ADD PRIMARY KEY (reg_no);"
 end
end


class CreateStudentStatusReports < ActiveRecord::Migration
  def change
    create_table :student_status_reports do |t|
     t.string  :student_id
     t.integer :mark
     t.timestamps
   end
 end
end    

Now I am using the following query to insert data into the StudentStatusReport Model on rails console.

e = StudentDetails.find("UG10001")
f = e.student_status_reports.create!(:mark => 40)

But I am getting the following error on console --

ActiveRecord::UnknownAttributeError: unknown attribute: student_details_id  

What could be the possible solution regarding this?
I have already defined the foreign and primary key in models and database, i don't know where I am going wrong. Tx..!


Solution

  • I think the problem is your foreign key. In the StudentStatusReport model you are defining it to be the student_id column in the student_status_reports table, but in the StudentDetails model it is (implicitly) defined as student_details_id (Rails guesses it to be the association name + _id unless you explicitly define it). So the error should get fixed by specifying the correct foreign_key in the parent_model:

    class StudentStatusReport < ActiveRecord::Base
      attr_accessible :student_id, :mark
      belongs_to :student_details, :class_name => "StudentDetails", :foreign_key => "student_id"
    end
    
    class StudentDetails < ActiveRecord::Base
      attr_accessible :student_id, :name
      has_many :student_status_reports, :foreign_key => "student_id"
    end
    

    Note that the student_id column in the student_details table is not actually used in the association, so you might consider removing it to make the association more clear.

    Finally, it's usually a good idea to stick to the default conventions in Rails (integer autoincrement primary keys named id, singular model names). But sometimes you just can't... :S