如何在rails迁移中将数据从一个表移动到另一个表? [英] How can I move data from one table to another in rails migration?
问题描述
我已经使用这些资源设置了一个rails站点:
用户(设计)
作者
我已经意识到,我需要将所有作者移到用户表上,因为我现在正在为这些用户设置角色。
目前我已经尝试以下迁移但没有任何工作,没有数据传输到users表:
class MoveAuthorsColumnDataToUsersTable< ActiveRecord :: Migration
def change
Author.find_each do | author |
User.find_or_create_by(
:username => author.name.downcase.gsub('',''),
:encrypted_password =>,
:电子邮件=>,
: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模型:
类作者< ActiveRecord :: Base
has_many:books,dependent::destroy
has_many:ideas,dependent::destroy
acceptance_nested_attributes_for:books
accepted_nested_attributes_for:ideas
validates_uniqueness_of:name
has_attached_file:头像,:styles => {:large => 980x760,:medium => 300x300>,:thumb => 100×100> 中},:default_url => /images/:style/missing.png
validates_attachment_content_type:avatar,:content_type => /\Aimage\/.*\Z/
end
user.rb model(devise)
class User< ActiveRecord :: Base
belongs_to:角色
def confirm_required?
false
end
#包含默认设计模块。其他可用的是:
#:confirmable,:lockable,:timeoutable和:omniauthable
devise:database_authenticatable,:可注册,
:可恢复,可记忆,可跟踪,可验证,,可确认
has_attached_file:头像,样式:{
large:600x450#,
medium:250x250#,
small:100x100#
},:default_url => /images/:style/filler.png
#validates_attachment_content_type:头像,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_tableauthors,force:true do | t |
t.stringname
t.text传记
t.datetimecreated_at
t.datetimeupdated_at
t.integerbook_id
t.stringavatar_file_name
t.stringavatar_content_type
t.integeravatar_file_size
t.datetimeavatar_updated_at
t.integeridea_id
end
create_tableusers,force:true do | t |
t.stringemail,默认值为,null:false
t.stringencrypted_password,默认值为,null:false
t.stringreset_password_token
t.datetimereset_password_sent_at
t.datetimeremember_created_at
t.integersign_in_count,默认值:0,null:false
t.datetimecurrent_sign_in_at
t.datetimelast_sign_in_at
t.stringcurrent_sign_in_ip
t.stringlast_sign_in_ip
t.datetimecreated_at
t.datetimeupdated_at
t.stringavatar_file_name
t.stringavatar_content_type
t.integeravatar_file_size
t.datetimeavatar_updated_at
t.stringusername
t.stringconfirm_token
t.datetimeconfirm_at
t.datetimeconfirmation_sent_at
t.integerrole_id
end
我试图达到的最终结果是将所有作者安全地转到用户作为postgres数据库中的条目,然后从那里我可以使用这些数据来完成用户等模型中需要重构的内容。
这将有助于帮助某人尝试找到正确的解决方案。我很确定很多人以前都在这里,并且头痛相同。
谢谢
在您的用户模型上,您有以下验证:
验证:头像,电子邮件,用户名, :密码,存在:true
但是,在迁移过程中,您设置 encrypted_password
到,不会通过
密码
的存在真实验证。 p>
作为附注 find_or_create_by
将执行两件事情之一,找到与您的哈希(用户名)匹配的第一条记录,等等),或者如果没有找到与该信息一起使用新的用途。如果您找到该记录,并且不创建它,您将需要在事后调用save。
我喜欢 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
I have set up a rails site with these resources:
users(devise) authors
I have realised that I need to move all authors over to users table because I am setting up roles for these users as an author now.
Currently I have tried the following migration but nothing worked and no data was transferred over to the users 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
I have got an author model setup with attributes in the controller, I am eventually going to transfer all author models relationships to users.
author.rb model:
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 model(devise)
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
Here is the schema for users and authors:
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
The end result I am trying to achieve here is to get all authors safely over to users as entries in the postgres database and then from there I can use this data to carry on finishing off what else needs refactoring in the models for users etc.
This will hopefully help someone try and find the right solution to what i am trying to do. I am pretty sure many people have been here before and had the same headache.
Thanks
On your user model you have these validations:
validates :avatar, :email, :username, :password, presence: true
However in your migration you're setting encrypted_password
to ""
which won't pass the presence true validation on password
.
As a side note find_or_create_by
is going to do 1 of two things, find the first record that matches your hash (username, etc) or if nothing is found create a new use with that info. If you find the record and don't create it, you'll want to call save after the fact.
I like first_or_initialize
so something like:
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
这篇关于如何在rails迁移中将数据从一个表移动到另一个表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!