如何在rails迁移中将数据从一个表移动到另一个表? [英] How can I move data from one table to another in rails migration?

查看:200
本文介绍了如何在rails迁移中将数据从一个表移动到另一个表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用这些资源设置了一个rails站点:



用户(设计)
作者



我已经意识到,我需要将所有作者移到用户表上,因为我现在正在为这些用户设置角色。



目前我已经尝试以下迁移但没有任何工作,没有数据传输到users表:

  class MoveAuthorsColumnDataToUsersTable< ActiveRecord :: Migration 
def change
Author.find_each do | author |
User.find_or_create_by(
:username => author.name.downcase.gsub('',''),
:encrypted_pa​​ssword =>,
:电子邮件=>,
: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_pa​​ssword,默认值为,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_pa​​ssword ,不会通过密码的存在真实验证。 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_pa​​ssword =>,
: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆