我正在尝试修复OS项目中的一个小错误。
目前,当创建标记时,它使用User对象的Memory地址:
tags_controller.rb
def create
...
new_tag = Tag.new(
user: @current_user)
尝试从数据库加载标记时会导致错误。我最初通过存储用户名的字符串来修复它,但我想将其设置为使用user_id
上的外键。
在代码模型中,我添加了belongs_to :user
,但它抱怨没有user_id。
我假设我需要生成迁移以删除现有的user
链接并添加user_id
。
我对RoR很新,并且不确定摆脱旧user
和使用user_id
的最佳方法是什么。我是否还需要在tags_controller或列表中修改当前代码?
答案 0 :(得分:1)
首先,我们要创建新列:
rails g migration AddUserToTags user:references
这将在db/migrations
class AddUserToTags < ActiveRecord::Migration
def change
add_reference :tags, :user, index: true # creates a user_id column
end
end
然后我们使用rake db:migrate
运行迁移。如果我们想在用户列中移动当前作为用户名存在的关系,我们可以这样做:
# comment out `belongs_to :user` in your tag model!
Tag.where.not(user: nil).find_each do |tag|
tag.user_id = User.find_by!(username: tag.user).id
tag.save!
end
然后我们想删除非正统的用户列以避免混淆。
rails g migration RemoveUserFromTags
。
将迁移编辑为如下所示:
class RemoveUserFromTags < ActiveRecord::Migration
def change
remove_column :tags, :user
remove_index :tags, :user if index_exists?(:tags, :user)
end
end
然后运行rake db:migrate
答案 1 :(得分:0)
让我解释一下它对你有用......
用户对象的内存地址
这是正确的 - 你基本上是在告诉Rails / Ruby保存 Object ,显然它不能归因于只有 具有user
属性把它保存到。
您的问题是您尝试在该字段中保存整个对象。如果您使用以下内容,它将按您的意愿工作:
new_tag = Tag.new(
user: @current_user.id)
然后,您可以通过将foreign_key
分配给user
:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :tags, foreign_key: "user"
end
这将允许您调用以下内容:
@tag = current_user.tags.new tag_params
-
既然你想学习如何去做,这就是 应该如何去做的事情:
#app/models/tag.rb
class Tag < ActiveRecord::Base
belongs_to :user
end
#app/models/user.rb
class User < ActiveRecord::Base
has_many :tags
end
以下是此association的说明:
我需要生成迁移以删除指向用户的现有链接
你是对的,但不要欺骗自己。你所说的“链接”只是一个专栏的标题......仅此而已。如果您的user
列已存在,则只需将其更改为user_id
(或将外键引用为“用户”,如上所述):
$ rails g migration ChangeUserForeignKey
#db/migrate/change_user_foreign_key.... .rb
class ChangeUserForeignKey < ActiveRecord::Migration
def change
rename_column :tags, :user, :user_id
end
end
$ rake db:migrate