Массовый даунсайд поле для всех записей в рельсах - PullRequest
11 голосов
/ 13 марта 2011

Когда я впервые реализовал модель User, я позволил пользователю вводить прописные или строчные буквы для своей информации для входа в систему. Проблема в том, что это мобильное приложение, а иногда и автокапки, чтобы пользователь не проходил аутентификацию. Я изменил метод CREATE, чтобы в первую очередь использовать электронную почту. Однако это приводит к тому, что люди с существующими учетными записями не согласуются

Так как я могу добавить миграцию для массового обновления поля электронной почты в таблице пользователей, чтобы уменьшить его?

Ответы [ 5 ]

23 голосов
/ 13 марта 2011

Наиболее эффективным способом было бы избежать использования итератора Ruby и делать это непосредственно в SQL.

Внутри обычного файла миграции вы можете использовать этот SQL для MySQL:

execute("UPDATE users SET email = LOWER(email)")
8 голосов
/ 13 ноября 2017

Вы можете просто пойти с

User.update_all('email = lower(email)')
6 голосов
/ 13 марта 2011

Самое простое решение - просто использовать код Ruby:

class DowncaseEmail < ActiveRecord::Migration
  def up
    User.all.each do |user|
      user.update_attributes :email => user.email.downcase
    end
  end
end

Как уже отмечали другие, это не самое эффективное решение.Я предпочитаю переносимость, а не производительность, но это зависит от количества записей, о которых мы говорим.

Более сложное, но все же переносимое решение зависит от некоторых функций, специфичных для БД:

class DowncaseEmail < ActiveRecord::Migration
  def up
    if %w[MySQL PostgreSQL].include? ActiveRecord::Base.connection.adapter_name
      execute "UPDATE users SET email = LOWER(email)"
    else
      User.all.each do |user|
        user.update_attributes email: user.email.downcase
      end
    end
  end
end

И Postgres , и MySQL поддерживают функцию LOWER. SQLite также поддерживает его, но только для кодировки ascii, которая, вероятно, подходит для электронных писем, но может вызвать ошибки (так как некоторые электронные письма могут содержать другие символы).Rails также потенциально поддерживает любое количество баз данных, поэтому использование этих функций может сделать ваше приложение привязанным к определенной БД.

3 голосов
/ 15 марта 2011

Никогда не беспокойтесь об оптимизации того, что вы собираетесь делать только один раз. Если у вас нет огромного количества пользователей, просто используйте методологию, которая вам наиболее знакома.(Хотя я бы порекомендовал просто запустить SQL-запрос.)

0 голосов
/ 19 января 2019

Вместо того, чтобы делать итерации, ниже приведено простейшее решение:

ActiveRecord::Base.connection.execute "UPDATE users SET email = LOWER(email)"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...