我在同一个Rails项目中使用SQLite3和MySQL,但是在两台不同的计算机上。我注意到,当我运行所有迁移时生成的schema.rb
对于两种环境看起来都不同。当我在SQLite3环境中运行迁移时,将从schema.rb
文件中删除以下语句。
add_index "places", ["user_id"], :name => "places_user_id_fk"
add_foreign_key "places", "users", :name => "places_user_id_fk"
请注意,我使用foreigner gem扩展了add_foreign_key
和remove_foreign_key
的迁移。
以下是与问题相关的迁移和模型:
# 20130123004056_create_places.rb
class CreatePlaces < ActiveRecord::Migration
def change
create_table :places do |t|
t.string :name
t.string :location
t.integer :user_id
t.timestamps
end
end
end
...
# 20130123234250_add_foreign_key.rb
class AddForeignKey < ActiveRecord::Migration
def change
add_foreign_key(:places, :users)
end
end
...
# user.rb
class User < ActiveRecord::Base
has_many :places
end
...
# place.rb
class Place < ActiveRecord::Base
belongs_to :user
end
问题:如何以SQLite3和MySQL可以处理的方式定义users
和places
之间的关系?
答案 0 :(得分:0)
foreigner
README明确说明
支持以下适配器:
- sqlite (外键方法是无操作)
因此,您的SQLite数据库没有设置的外键约束,因为foreigner
不支持它们。从SQLite数据库生成db/schema.rb
时,这就是没有指定外键的原因。
Rails Guide on Migrations提到外键很多
如果需要执行特定于数据库的任务(例如创建外键约束),则
execute
方法允许您执行任意SQL
甚至有how to add/remove a foreign key的例子。
在第一次使用Rails时使用foreigner
,我建议您从Gemfile
中删除
execute
迁移方法(并确保所有不同的RDBMS'支持您放入execute
方法中的任何内容) < / LI>
作为评论中的pointed out,SQLite在创建表后缺乏对添加外键的支持;它们无法通过Rails中的未来迁移添加。 我个人建议您使用选项1或3 ,因为在满足SQLite限制但同时具有相同最终结果的迁移中通过execute
命令创建解决方案会更加困难在其他RDMS上。