Как универсально пропустить касания базы данных при прекомпиляции ресурсов в Heroku - PullRequest
32 голосов
/ 15 сентября 2011

Я развертываю приложение Rails 3.1 в стеке Heroku Cedar. С Heroku Cedar и Rails 3.1 вы можете самостоятельно скомпилировать ресурсы, позволить Heroku скомпилировать их, когда вы нажимаете (во время «компиляции слагов»), или сделать так, чтобы они были скомпилированы точно во время работы приложения. Бег. Я хочу сделать средний вариант, позволяя Heroku предварительно скомпилировать ресурсы.

Когда Heroku запускает задачу assets: precompile, она выдает ошибку "не удалось подключиться к серверу" , потому что приложение пытается подключиться к базе данных, но на этом этапе компиляции слагов база данных недоступна. Отсутствие подключения к базе данных ожидается и неизбежно на этом этапе. Я ищу способ пройти дальше, потому что соединение с базой данных не имеет решающего значения для прекомпиляции ресурсов.

Часть моего приложения, которая пытается подключиться к базе данных, - это Devise. В файле rout.rb есть строка devise_for :users, которая хочет посмотреть на модель User.

Я мог бы просто написать грабли, которые заглушают devise_for и делают это предварительным требованием ресурсов: precompile. Я думаю, что это решило бы мою проблему, но Я ищу более универсальное решение , которое я мог бы использовать в любом Rails 3.1 приложении с этой проблемой на Heroku.

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

Очевидно, что если приложению нужно читать / записывать данные во время запуска, мы не можем это заглушить, но можем ли мы подделать каждую модель ActiveRecord автоматически?

Ответы [ 10 ]

46 голосов
/ 25 октября 2011

добавить это в config / application.rb

config.assets.initialize_on_precompile=false                                                  

Мне понадобилось время, чтобы выследить это ... добавив его в config / environment / *. Rb НЕ работало

ОБНОВЛЕНИЕ : с рельсами не работает 4

13 голосов
/ 03 января 2012

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

Сначала необходимо установить плагин labs :

$ heroku plugins:install http://github.com/heroku/heroku-labs.git

затем включите функцию user-env-compile labs :

$ heroku labs:enable user-env-compile --app your-app-name
5 голосов
/ 23 сентября 2011

Для меня проблема activerecord, вызывающая instantiate_observer in lib/active_record/railtie.rb:92. Это загрузит наблюдателей и соответствующие модели. has_and_belongs_to_many затем подключается к БД.

Я думаю, что переопределю этот метод, когда присутствует ENV["RAILS_ASSETS_PRECOMPILE"], который используется devise в исправлении, связанном с Брэдли.

РЕДАКТИРОВАТЬ: Таким образом, этот фрагмент исправил это для меня:

namespace :assets do
  # Prepend the assets:precompile_prepare task to assets:precompile.
  task :precompile => :precompile_prepare

  # This task will be called before assets:precompile to optimize the
  # compilation, i.e. to prevent any DB calls.
  task 'precompile_prepare' do
    # Without this assets:precompile will call itself again with this var set.
    # This basically speeds things up.
    ENV['RAILS_GROUPS'] = 'assets'

    # Devise uses this flag to prevent connecting to the db.
    ENV['RAILS_ASSETS_PRECOMPILE'] = 'true'

    # Prevent loading observers which will load the models which in turn may hit
    # the DB.
    module ActiveModel::Observing::ClassMethods
      def instantiate_observers; end
    end

    # Prevent route drawing because certain gems might get called which will hit
    # the DB.
    class ActionDispatch::Routing::RouteSet
      def draw; end
    end
  end
end
3 голосов
/ 22 июля 2014

Обходной путь для Rails (4.2 edge):

Добавить следующее как /config/initializers/precompile.rb:

module Precompile

  # Public: ignore the following block during rake assets:precompile
  def self.ignore

    unless ARGV.any? { |e| e == 'assets:precompile' }
      yield
    else
      line = caller.first
      puts "Ignoring line '#{line}' during precompile"
    end

  end

end

и используйте его в своем routes.rb так:

Precompile.ignore { ActiveAdmin.routes(self) }
3 голосов
/ 23 сентября 2011

РЕДАКТИРОВАТЬ: Этот ответ устарел и больше не работает - см. Ответ fringd.

Не совсем универсальная заглушка, но devise добавил проверку сейчас, чтобы исправить эту конкретную проблему.См. Проблемы и fix на Github.Предоставляя конфигурацию среды RAILS_ASSETS_PRECOMPILE, devise должен пропустить построение маршрутов

1 голос
/ 14 ноября 2011

Heroku добавил неофициальный флаг, чтобы сделать среду (т. Е. Также БД) доступной во время предварительной компиляции. Просто попросите их включить его, и зависимости БД во время прекомпиляции ресурсов больше не будут проблемой. Не уверен, если / когда этот флаг официально доступен, или просто будет новым по умолчанию.

1 голос
/ 21 сентября 2011

Я вставил это в 'lib / tasks / assets.rake' и смог получить ресурсы: прекомпилировать, чтобы действительно добиться успеха. Это должно работать до тех пор, пока вы на самом деле не обращаетесь к базе данных в результате требования вашей среды. Это, очевидно, не поможет с ActiveRecord, но должно работать для всех приложений на основе mongoid.

task 'assets:precompile' => 'assets:stub_mongoid'

task 'assets:stub_mongoid' do
  def Mongoid.load!(*args)
    true
  end
end
0 голосов
/ 22 апреля 2016

Отключить AR:

config = Rails.application.config
def config.database_configuration
  {}
end

ar = ActiveRecord::Base
def ar.establish_connection
end
0 голосов
/ 11 февраля 2015

Мне не хватает репутации, чтобы комментировать, поэтому вот еще один ответ.

Это правда, что самый лучший ответ @ fringd не работает на Rails 4. Однако я нашел этот метод для работы:

https://iprog.com/posting/2013/07/errors-when-precompiling-assets-in-rails-4-0

Хотя я переставил переменные BASH следующим образом:

~$ RAILS_ENV=production DATABASE_URL=postgresql://user:pass@127.0.0.1/dbname bundle exec rake assets:precompile

Кстати, это фантастическая помощь, если вам нужно создать образ Docker. Поместите эту строку в свой Dockerfile, чтобы ваша БД могла находиться в другом контейнере, и контейнерам вашего приложения не нужно предварительно компилировать ресурсы при каждом запуске!

0 голосов
/ 01 октября 2011

Spork.trap_method также является интересным решением проблемы маршрутов Devise для вызова модели в начале процесса загрузки.Решение не может быть применено напрямую AFAIK, но оно решает ту же проблему, поэтому оно может вдохновить кого-то.

Spork.trap_method

...