我有一个用户的rails表,列first_name和last_name等。 我如何将这两者合并在一起?或者我如何创建一个名为name的新列并从这两列添加数据? 基本上我需要一个名为name的列,它是first_name和last_name的串联。
答案 0 :(得分:6)
正如Richard Brown所回答的,如果要将连接的字符串保存到数据库,则应创建一个迁移。
rails g migration add_fullname_to_users fullname
然后在生成的迁移中运行一个sql以更新所有记录
# mysql
User.update_all('fullname = CONCAT(first_name, " ", last_name)')
# postgre
User.update_all("fullname = (first_name || ' ' || last_name)")
但我建议你保留当前的设置,只需在模型中创建一个名为fullname的方法
# user.rb
def fullname
"{first_name} #{last_name}"
end
哪个更好,因为您可以访问first_name
和last_name
答案 1 :(得分:3)
如果您想确保可以回滚,可以在迁移文件中执行类似的操作。
def up
add_column :your_table, :name, :string
YourClass.all.each do |person|
person.update_attributes! :name => person.first_name + " " + person.last_name
end
remove_column :your_table, :first_name
remove_column :your_table, :last_name
end
你的回滚方法:
def down
add_column :your_table, :first_name, :string
add_column :your_table, :last_name, :string
YourClass.all.each do |person|
person.update_attributes! :first_name => person.name.match(/\w+/)[0]
person.update_attributes! :last_name => person.name.match(/\w+/)[1]
end
remove_column :your_table, :name
end
答案 2 :(得分:0)
创建迁移以添加新字段:
rails g migration AddNameToTableName name
您可以编写一个rake任务来进行连接。
TableName.all.each do { |row| row.update_attributes(name: "#{row.first_name} #{row.last_name}") }
您可以从rails控制台执行该操作,但我喜欢可重复的数据库更新,所以我更喜欢rake任务。
答案 3 :(得分:0)
\ w正则表达式匹配器和上面示例中的空格连接对我来说是个问题,尽管我遇到了相反的问题,将名称拆分为名字和姓氏。相反,考虑使用我最终得到的东西。首先备份数据库,然后在开发中测试它!
def up # Split name into first and last
add_column :people, :first_name, :string
add_column :people, :last_name, :string
Person.all.each do |person|
person.update_column(:first_name, person.attributes["name"].rpartition(" ").first)
person.update_column(:last_name, person.attributes["name"].rpartition(" ").last)
person.save(:validate => false)
end
remove_column :people, :name
end
def down # Merge first and last into name
add_column :people, :name, :string
Person.all.each do |person|
person.update_column(:name, [person.attributes["first_name"].to_s, person.attributes["last_name"].to_s].reject(&:blank?).join(" "))
person.save(:validate => false)
end
remove_column :people, :first_name
remove_column :people, :last_name
end
这可以避免在其中一个名称为nil的情况下插入杂散空格,并且还可以更有效地将全名拆分为名字和姓氏;具体来说,通过拆分名称中的 last 空格,因为“First Middle”“Last”更像是人类兼容的分割,而不是“First”“Middle Last”。见例子:
# Before split
> puts p.name.inspect
"Prince"
"Test User"
"Jean Luc Picard"
# After split
> puts p.first_name.inspect + " " + p.last_name.inspect
"" "Prince"
"Test" "User"
"Jean Luc" "Picard"
我的主要抱怨是“王子”应该是名字而不是姓氏,但是根据你的数据库限制,它可能需要进入last_name字段。
答案 4 :(得分:0)
在我的带有用户模型的rails 4应用程序中,我生成了我的迁移文件
rails g migration RemoveFirstLastNameColumnsFromUser
然后我放入
class RemoveFirstLastNameColumnsFromUser < ActiveRecord::Migration
def up
add_column :users, :name, :string
User.all.each do |u|
u.update! name: "#{u.first_name} #{u.last_name}"
end
remove_column :users, :first_name
remove_column :users, :last_name
end
def down
add_column :users, :first_name, :string
add_column :users, :last_name, :string
User.all.each do |u|
n = u.name
u.update! last_name: n.slice!(/\w+\z/)
u.update! first_name: n.strip
end
remove_column :users, :name, :string
end
end
此#down
方法将考虑具有多个空格的名称。