5

ユーザーの Rails テーブルがあり、列 first_name や last_name などがあります。これら 2 つをマージするにはどうすればよいですか? または、name という名前の新しい列を作成し、これら 2 つの列からデータを追加するにはどうすればよいですか? 基本的に、first_name と last_name を連結した name という列が必要です。

4

5 に答える 5

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

于 2013-03-08T05:42:25.777 に答える
0

新しいフィールドを追加する移行を作成します。

rails g migration AddNameToTableName name

結合を行うための rake タスクを作成できます。

TableName.all.each do { |row| row.update_attributes(name: "#{row.first_name} #{row.last_name}") }

これは Rails コンソールから実行できますが、私は反復可能なデータベース更新が好きなので、rake タスクを好みます。

于 2013-03-08T05:36:54.203 に答える
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

これにより、名前の 1 つが nil の場合に不要なスペースを挿入することが回避され、フルネームが姓名に効果的に分割されます。具体的には、「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 フィールドに入る必要があるかもしれません。

于 2013-09-20T23:54:59.297 に答える