这是我的Schema.rb
Schema.rb
ActiveRecord::Schema.define(version: 20170617073406) do
create_table "actions", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "posts", force: :cascade do |t|
t.string "post_id"
t.datetime "timestamp"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "user_id"
t.datetime "last_activity"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
这是我的三个模型类。
Action.rb
class Action < ApplicationRecord
belongs_to :post
has_many :users, :foreign_key => 'user_user_id'
end
Post.rb
class Post < ApplicationRecord
has_many :actions, :foreign_key => 'action_id'
end
User.rb
class User < ApplicationRecord
has_many :actions, :foreign_key => 'action_id'
end
我正在尝试将Action
对象的实例添加到Post
模型对象中。
post = Post.find(post_id=post_id)
current_action = post.actions.find_or_create_by(name: "like")
它给我以下错误:
SQLite3::SQLException: no such column: actions.action_id: SELECT "actions".* FROM "actions" WHERE "actions"."action_id" = ? AND "actions"."name" = ? LIMIT ?
我是Ruby on Rails的新手,来自Django背景。请帮我解决这个问题。
答案 0 :(得分:3)
行动需要与用户相关多少......
如果您想要多对多关联,则需要使用另一个表(即加入模型):
class Action < ApplicationRecord
belongs_to :post
has_many :user_actions
has_many :users, through: :user_actions
end
class User < ApplicationRecord
has_many :user_actions
has_many :actions, through: :user_actions
end
class UserAction < ApplicationRecord
belongs_to :action
belongs_to :user
end
我要存储的ID比Integer可以做的长。
您可以在迁移中指定自己的id
,并避免添加额外的action_id
:
class CreateActions < ActiveRecord::Migration[5.1]
def change
create_table :actions, id: false do |t|
t.string :id, null: false
t.timestamps
end
add_index :actions, :id , unique: true
end
end
通过上述设置,您无需在foreign_key
中指定任何Post
, ActiveRecord 将使用默认值(即action_id
):< / p>
class Post < ApplicationRecord
has_many :actions
end
关于关联和外键的注释(以及为什么会出现该错误):
每当您创建关联时,必须在包含foreign_key
一面的表格中创建belongs_to
,因为 ActiveRecord 会在那里查找该关键字。
即使您未指定belongs_to
,对该表的has_many
引用仍会查找foreign_key
。
所以,当你添加
has_many :actions, :foreign_key => 'action_id'
您告诉 ActiveRecord 在action_id
表中查找actions
列,但尚未在actions
表中创建这些列。
在建议的解决方案中,外键位于连接表模型(即UserActions)上,因此您必须创建一个迁移以包含它们:
rails g migration CreateUserActions user:references action:references
答案 1 :(得分:2)
在命令行中运行迁移:
rails generate migration add_post_to_actions post:belongs_to
rake db:migrate
然后更新:
class Action < ApplicationRecord
belongs_to :post
# ...
end
class Post < ApplicationRecord
self.primary_key = 'post_id'
has_many :actions
# ...
end
class User < ApplicationRecord
self.primary_key = 'user_id'
# ...
end
post_id
列添加到actions
表,然后使用外部约束对其进行索引schema.rb
中写入的内容,尽管每次运行迁移时都会更新schema.rb
(在数据库已经迁移/更新之后)。