如何在 rails 迁移中将数据从一个 table 移动到另一个?
How can I move data from one table to another in rails migration?
我已经使用这些资源建立了一个 rails 站点:
用户(设计)
作者
我意识到我需要将所有作者移交给用户table,因为我现在正在为这些用户设置作者角色。
目前我尝试了以下迁移,但没有任何效果,也没有数据传输给用户table:
class MoveAuthorsColumnDataToUsersTable < ActiveRecord::Migration
def change
Author.find_each do |author|
User.find_or_create_by(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
end
end
end
我在控制器中设置了一个带有属性的作者模型,我最终会将所有作者模型关系转移给用户。
author.rb 型号:
class Author < ActiveRecord::Base
has_many :books, dependent: :destroy
has_many :ideas, dependent: :destroy
accepts_nested_attributes_for :books
accepts_nested_attributes_for :ideas
validates_uniqueness_of :name
has_attached_file :avatar, :styles => { :large => "980x760", :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
user.rb 模型(设计)
class User < ActiveRecord::Base
belongs_to :role
def confirmation_required?
false
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_attached_file :avatar, styles: {
large: "600x450#",
medium: "250x250#",
small: "100x100#"
}, :default_url => "/images/:style/filler.png"
#validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
validates :avatar, :email, :username, :password, presence: true
end
这是用户和作者的架构:
create_table "authors", force: true do |t|
t.string "name"
t.text "biography"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "book_id"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "idea_id"
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "username"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.integer "role_id"
end
我在这里试图实现的最终结果是将所有作者作为 postgres 数据库中的条目安全地交给用户,然后我可以从那里使用这些数据继续完成模型中还需要重构的部分对于用户等
这将有望帮助某人尝试找到我正在尝试做的事情的正确解决方案。我很确定很多人以前来过这里并且有同样的头痛。
谢谢
在你的用户模型上你有这些验证:
validates :avatar, :email, :username, :password, presence: true
但是在您的迁移中,您将 encrypted_password
设置为 ""
,这不会通过 password
上的存在真实验证。
旁注 find_or_create_by
将做两件事中的一件,找到与您的散列(用户名等)匹配的第一条记录,或者如果没有找到,请使用该信息创建新用途。如果您找到了记录但没有创建它,您将需要事后调用保存。
我喜欢 first_or_initialize
所以有点像:
Author.find_each do |author|
user = User.first_or_initialize(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
user.save!
end
假设:
1.you 已经在用户 table 中创建了所有必需的列(就像在作者 table 中一样)。
2。您只需要将所有作者记录复制到用户即可。
在以下位置创建您的 copy_author_to_user.rb 文件!
# db/scripts/copy_author_to_user.rb
require 'rubygems'
Author.all.each do |a|
user = User.new(
:username => a.name.downcase.strip,
:encrypted_password => '',
:email => '',
:avatar_file_name => a.avatar_updated_at,
:avatar_content_type => a.avatar_content_type,
:avatar_file_size => a.avatar_file_size,
:avatar_updated_at => a.avatar_updated_at,
:role_id => "3"
)
user.save!
end
then from console run :
$rails runner db/scripts/copy_author_to_user.rb
我已经使用这些资源建立了一个 rails 站点:
用户(设计) 作者
我意识到我需要将所有作者移交给用户table,因为我现在正在为这些用户设置作者角色。
目前我尝试了以下迁移,但没有任何效果,也没有数据传输给用户table:
class MoveAuthorsColumnDataToUsersTable < ActiveRecord::Migration
def change
Author.find_each do |author|
User.find_or_create_by(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
end
end
end
我在控制器中设置了一个带有属性的作者模型,我最终会将所有作者模型关系转移给用户。
author.rb 型号:
class Author < ActiveRecord::Base
has_many :books, dependent: :destroy
has_many :ideas, dependent: :destroy
accepts_nested_attributes_for :books
accepts_nested_attributes_for :ideas
validates_uniqueness_of :name
has_attached_file :avatar, :styles => { :large => "980x760", :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
end
user.rb 模型(设计)
class User < ActiveRecord::Base
belongs_to :role
def confirmation_required?
false
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_attached_file :avatar, styles: {
large: "600x450#",
medium: "250x250#",
small: "100x100#"
}, :default_url => "/images/:style/filler.png"
#validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
validates :avatar, :email, :username, :password, presence: true
end
这是用户和作者的架构:
create_table "authors", force: true do |t|
t.string "name"
t.text "biography"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "book_id"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.integer "idea_id"
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "avatar_file_name"
t.string "avatar_content_type"
t.integer "avatar_file_size"
t.datetime "avatar_updated_at"
t.string "username"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.integer "role_id"
end
我在这里试图实现的最终结果是将所有作者作为 postgres 数据库中的条目安全地交给用户,然后我可以从那里使用这些数据继续完成模型中还需要重构的部分对于用户等
这将有望帮助某人尝试找到我正在尝试做的事情的正确解决方案。我很确定很多人以前来过这里并且有同样的头痛。
谢谢
在你的用户模型上你有这些验证:
validates :avatar, :email, :username, :password, presence: true
但是在您的迁移中,您将 encrypted_password
设置为 ""
,这不会通过 password
上的存在真实验证。
旁注 find_or_create_by
将做两件事中的一件,找到与您的散列(用户名等)匹配的第一条记录,或者如果没有找到,请使用该信息创建新用途。如果您找到了记录但没有创建它,您将需要事后调用保存。
我喜欢 first_or_initialize
所以有点像:
Author.find_each do |author|
user = User.first_or_initialize(
:username => author.name.downcase.gsub(' ',''),
:encrypted_password => "",
:email => "",
:avatar_file_name => author.avatar_updated_at,
:avatar_content_type => author.avatar_content_type,
:avatar_file_size => author.avatar_file_size,
:avatar_updated_at => author.avatar_updated_at,
:role_id => "3"
)
user.save!
end
假设: 1.you 已经在用户 table 中创建了所有必需的列(就像在作者 table 中一样)。
2。您只需要将所有作者记录复制到用户即可。
在以下位置创建您的 copy_author_to_user.rb 文件!
# db/scripts/copy_author_to_user.rb
require 'rubygems'
Author.all.each do |a|
user = User.new(
:username => a.name.downcase.strip,
:encrypted_password => '',
:email => '',
:avatar_file_name => a.avatar_updated_at,
:avatar_content_type => a.avatar_content_type,
:avatar_file_size => a.avatar_file_size,
:avatar_updated_at => a.avatar_updated_at,
:role_id => "3"
)
user.save!
end
then from console run :
$rails runner db/scripts/copy_author_to_user.rb