Ruby 1.8.7-p249,Rails 2.3.8,SQLite3。
我想以编程方式创建2个表并定义它们之间的父子关系。 foreign_key方法在db迁移中有效,但在我的ActiveRecord :: Schema.define块中的代码中不起作用。
如何以编程方式创建外键?
代码:
# To change this template, choose Tools | Templates
# and open the template in the editor.
require "rubygems"
require "active_record"
require "logger"
require "pp"
ActiveRecord::Base.logger = Logger.new($stdout)
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "../db/development_mp.sqlite3"
)
ActiveRecord::Schema.define do
create_table :orders, :force => true do |t|
t.string :name
t.timestamps
end
create_table :invoices, :force => true do |t|
t.integer :order_id
t.timestamps
end
# Error!
foreign_key(:invoices, :order_id, :orders)
end
错误:
-- foreign_key(:invoices, :order_id, :orders) D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/migration.rb:352:in `send': undefined method `foreign_key' for
#<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x554f2f8> (NoMethodError)
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/migration.rb:352:in `method_missing'
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/migration.rb:328:in `say_with_time'
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/migration.rb:328:in `say_with_time'
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/migration.rb:348:in `method_missing'
from D:/prg/Ruby/Pragmatic.Agile-Web-Development-With-Rails-Third-Edition/active_record_basics/lib/has_one_mp.rb:29
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/schema.rb:47:in `instance_eval'
from D:/Ruby/bitnami-rubystack-2.1-0/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/schema.rb:47:in `define'
from D:/prg/Ruby/Pragmatic.Agile-Web-Development-With-Rails-Third-Edition/active_record_basics/lib/has_one_mp.rb:16
答案 0 :(得分:0)
你已经大部分在那里,因为你使用[parent_table_name] _id的约定作为外键(Good work!)。 Rails使用约定优于配置模型,因此,由于您选择在发票表中命名外键order_id,Rails将自动确定order_id是order.id主键的外键。您需要做的就是在模型中指定has_many和belongs_to属性。
/app/models/order.rb
class Order < ActiveRecord::Base
has_many :invoices
end
----------
/app/models/invoice.rb
class Invoice < ActiveRecord::Base
belongs_to :order
end
注意:如果您在发票表中将外键命名为order_id以外的东西(在Rails中不推荐),让我们说schmorder_id,那么您可以指定它是订单模型中的外键,如下所示:
/app/models/order.rb
class Order < ActiveRecord::Base
#if the foreign_key in your invoices table was named schmorder_id...
has_many :invoices, :foreign_key => "schmorder_id"
end