Rails更新has_one关系

时间:2017-07-25 15:46:04

标签: ruby-on-rails activerecord

我已将iconfolio添加到我的角色模型中。每个字符has_one :iconfolio

character.rb

has_one :iconfolio, dependent: :destroy
accepts_nested_attributes_for :iconfolio
before_validation do
 self.create_iconfolio unless iconfolio
end

以下是迁移文件:

class CreateIconfolios < ActiveRecord::Migration
  def change
    create_table :iconfolios do |t|
      t.integer :character_id

      t.string :icon_url

      t.timestamps null: false
    end
    add_index :iconfolios, :character_id
  end
end

iconfolio类:

iconfolio.rb

class Iconfolio < ActiveRecord::Base

  belongs_to :character

  validates :character_id, presence: true

  before_create do
    self.icon_url = '/assets/icon1.png'
  end

end

首先,如何确保为每个iconfolio创建character

其次,如何更新character_id列中的所有行?每个character_id记录的iconfolio值都不同。可以在控制台中更新icon_url列:

Iconfolio.all.update_all(person_normal_icon_url: '/assets/icon1.png')

1 个答案:

答案 0 :(得分:1)

最简单的方法是创建一个默认模板iconfolio和update_all字符记录,就像使用Iconfolio一样。如果您的数据库不是很大,您可以遍历Character.all并为它们分配一个iconfolio。请注意,这将每行实例化一个对象,并且比update_all更耗时。实例化它们的好处是它不会绕过您的验证。在控制台中编写一个块,遍历每条记录,并在每个字符中查找或创建一个iconfolio,如:

  Character.all.find_each do |char|
     if char.iconfolio.blank?
          Iconfolio.create(character_id: char.id, whatever_other_params: put_here)
     end
  end

然后在Character模型中创建一个after_create,为未来的新角色创建并指定一个iconfolio。类似的东西:

after_create :make_an_iconfolio

def make_an_iconfolio
   Iconfolio.create(character_id: self.id, other params here)
end

作为旁注,在create_table迁移中添加关系的Rails方法是:

def change
    create_table :iconfolios do |t|
      t.belongs_to :character, index: true

这让你和其他人更清楚这是一种关系,并从索引中节省了额外的代码。