我在数据库中已有一堆character
个模型。每个character has_one :iconfolio
。我迁移了数据库以将icon_url
和post_url
属性添加到iconfolio
模型,因此我尝试使用rails控制台更新数据库中的所有iconfolio
模型。
但是,为每个现有记录设置正确的属性并非易事,因此我还添加了before_create
到iconfolio
,这将正确设置icon_url
和{新post_url
和characters
的{1}}属性。但是,如何强制此代码执行数据库中已存在的iconfolios
和characters
?
在我尝试的控制台中:
iconfolios
但它不会更新数据库。它似乎删除了记录:
Character.all.find_each do |char|
char.create_iconfolio
end
我也尝试过:
(0.4ms) COMMIT
Iconfolio Load (0.2ms) SELECT "iconfolios".* FROM "iconfolios" WHERE "iconfolios"."character_id" = $1 LIMIT 1 [["character_id", 46]]
(0.1ms) BEGIN
SQL (0.2ms) DELETE FROM "iconfolios" WHERE "iconfolios"."id" = $1 [["id", 46]]
这产生了:
Character.all.find_each do |char|
Iconfolio.create(character_id: char.id)
end
看起来很有前景,但数据库仍未更新。 (我已尝试重启服务器等)。
我做错了什么?
iconfolio.rb
(0.2ms) BEGIN
Character Load (0.6ms) SELECT "characters".* FROM "characters" WHERE "characters"."id" = $1 LIMIT 1 [["id", 2]]
SQL (0.5ms) INSERT INTO "iconfolios" ("character_id", "created_at", "updated_at", "person_url", "followed_url", "icon_url", "post_url") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["character_id", 2], ["created_at", "2017-08-02 13:27:35.897842"], ["updated_at", "2017-08-02 13:27:35.897842"], ["person_url", "/assets/icon1.png"], ["followed_url", "/assets/icon2.png"], ["icon_url", "/assets/icon7.png"], ["post_url", "/assets/icon8.png"]]
(0.4ms) COMMIT
答案 0 :(得分:2)
我喜欢做的是将before_create移动到方法
class Iconfolio
belongs_to :character
validates :character_id, presence: true
before_create :set_attributes
def set_attributes
if self.character.type.is_a? User
self.icon_url = '/assets/icon5.png'
self.post_url = '/assets/icon6.png'
else
self.icon_url = '/assets/icon7.png'
self.post_url = '/assets/icon8.png'
end
end
end
现在您可以在需要时随时拨打电话
答案 1 :(得分:1)
当我评论你的问题时,你不应该使用Rails'控制台更新现有数据以尊重新的数据库结构(我可以提供示例,如果您需要,不应该这样做)。
您应该在更改de DB结构的完全相同的迁移中更新此数据:
# 1234_your_migration.rb
def up
# changing the DB structure
add_column :iconfolios, :icon_url, :string
add_column :iconfolios, :post_url, :string
# updating the current data
Iconfolio.includes(:character).find_each do |iconfolio|
if self.character.type.is_a? User
self.icon_url = '/assets/icon5.png'
self.post_url = '/assets/icon6.png'
else
self.icon_url = '/assets/icon7.png'
self.post_url = '/assets/icon8.png'
end
end
end
这可能是一次繁重的迁移,具体取决于您在数据库中拥有的Iconfolio记录的数量。您可以按此处所示执行或定义方法Iconfolio#update_icon_and_post_urls
,但此方法仅在Iconfolio创建的上下文中或在迁移中使用,因此可能过度使用,从长远来看污染您的Iconfolio模型重要的是,在重新运行迁移时可能会导致问题(请参阅我对该答案的评论)。