Опасен ли ввод данных с помощью приспособлений в Ruby on Rails

StackOverflow https://stackoverflow.com/questions/984479

Вопрос

У меня есть устройства с исходными данными, которые должны храниться в моей базе данных (страны, регионы, перевозчики и т.д.).У меня есть задача rake db: seed, которая будет заполнять базу данных.

namespace :db do
  desc "Load seed fixtures (from db/fixtures) into the current environment's database." 
  task :seed => :environment do
    require 'active_record/fixtures'

    Dir.glob(RAILS_ROOT + '/db/fixtures/yamls/*.yml').each do |file|
      Fixtures.create_fixtures('db/fixtures/yamls', File.basename(file, '.*'))
    end
  end
end

Я немного обеспокоен, потому что эта задача очищает мою базу данных и загружает исходные данные.Тот факт, что это даже возможно сделать более одного раза на производстве, пугает меня до чертиков.Нормально ли это, и должен ли я просто быть осторожным?Или люди обычно каким-то образом защищают подобную задачу?

Это было полезно?

Решение

Заполнение данных приборами - крайне плохая идея.

Приспособления не проверяются, и поскольку большинство разработчиков Rails не используют ограничения базы данных, это означает, что вы можете легко вставить неверные или неполные данные в свою производственную базу данных.

Устройства также по умолчанию устанавливают странные идентификаторы первичных ключей, что не обязательно является проблемой, но раздражает при работе.

Для этого есть множество решений.Мой личный фаворит - это задача rake, которая запускает Ruby-скрипт, который просто использует ActiveRecord для вставки записей.Это то, что Rails 3 будет делать с db:seed, но вы легко можете написать это сами.

Я дополняю это методом, который я добавляю в ActiveRecord::Base под названием create_or_update.Используя это, я могу запускать начальный скрипт несколько раз, обновляя старые записи вместо того, чтобы генерировать исключение.

Некоторое время назад я написал статью об этих методах под названием Загрузка исходных данных.

Другие советы

Что касается первой части вашего вопроса, да, я бы просто принял некоторые меры предосторожности для запуска подобной задачи в рабочей среде.Я установил подобную защиту в своей задаче начальной загрузки / заполнения:

task :exit_or_continue_in_production? do
  if Rails.env.production?
    puts "!!!WARNING!!! This task will DESTROY " +
         "your production database and RESET all " +
         "application settings"
    puts "Continue? y/n"
    continue = STDIN.gets.chomp
    unless continue == 'y'
      puts "Exiting..."
      exit! 
    end
  end
end

Я создал в этом суть для некоторого контекста.

Что касается второй части вопроса - обычно вы действительно хотите двух вещей:а) очень простое заполнение базы данных и настройка приложения для разработки, и б) загрузка приложения на рабочий сервер (например:вставка пользователя-администратора, создание папок, от которых зависит приложение, и т.д.).

Я бы использовал fixtures для посева при разработке - тогда все члены команды видят одни и те же данные в приложении, и то, что есть в приложении, согласуется с тем, что есть в тестах.(Обычно я заворачиваю rake app:bootstrap, rake app:seed rake gems:install, и т.д. в rake app:install таким образом, каждый может работать над приложением, просто клонировав репозиторий и выполнив эту единственную задачу.)

Однако я бы никогда не использовал приспособления для заполнения / начальной загрузки на рабочем сервере.Рельсы' db/seed.rb действительно подходит для этой задачи, но вы, конечно, можете использовать ту же логику в своей собственной rake app:seed задача, как указывали другие.

Rails 3 решит это за вас, используя начальный файл.rb.

http://github.com/brynary/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb

Мы разработали ряд лучших практик, которые мы используем для заполнения данных.Мы в значительной степени полагаемся на начальный уровень, и у нас есть некоторые уникальные требования, поскольку нам необходимо создать многопользовательские системы.Вот несколько лучших практик, которые мы использовали:

  1. Светильники - не лучшее решение, но вы все равно должны хранить свои исходные данные во что-то другое, кроме Ruby.Код Ruby для хранения исходных данных имеет тенденцию повторяться, а хранение данных в анализируемом файле означает, что вы можете написать универсальный код для согласованной обработки исходных данных.
  2. Если вы собираетесь потенциально обновить начальные данные, используйте столбец маркера с именем что-то вроде code чтобы привести ваш файл seeds в соответствие с вашими фактическими данными.Никогда не полагайтесь на согласованность идентификаторов в разных средах.
  3. Подумайте о том, как вы хотите обработать обновление существующих исходных данных.Есть ли какая-либо вероятность того, что пользователи изменили эти данные?Если да, то должны ли вы сохранять информацию пользователя, а не заменять ее исходными данными?

Если вас интересуют некоторые из способов, которыми мы осуществляем посев, мы упаковали их в драгоценный камень под названием Семеноматический.

Как насчет того, чтобы просто удалить задачу с вашего рабочего сервера после заполнения базы данных?

Мне только что пришла в голову интересная идея...

что, если бы вы создали \db\seeds\ и добавили файлы в стиле миграции:

файл:200907301234_add_us_states.rb

class AddUsStates < ActiveRecord::Seeds

  def up
    add_to(:states, [
      {:name => 'Wisconsin', :abbreviation => 'WI', :flower => 'someflower'},
      {:name => 'Louisiana', :abbreviation => 'LA', :flower => 'cypress tree'}
      ]
    end
  end

  def down
    remove_from(:states).based_on(:name).with_values('Wisconsin', 'Louisiana', ...)
  end
end

поочередно:

  def up
    State.create!( :name => ... )
  end

Это позволило бы вам запускать миграции и начальные компоненты в порядке, который позволил бы им сосуществовать более мирно.

мысли?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top