Подтвердить что ты не робот

Как универсально пропускать штрихи базы данных при предварительной компиляции активов на Heroku

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

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

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

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

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

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

4b9b3361

Ответ 1

EDIT: этот ответ устарел и больше не работает. См. ответ fringd.

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

Ответ 2

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

config.assets.initialize_on_precompile=false                                                  

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

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

Ответ 3

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

Ответ 4

Для меня проблема - это активировать вызов instantiate_observer в lib/active_record/railtie.rb:92. Это загрузит наблюдателей и соответствующие модели. has_and_belongs_to_many затем соединяется с db.

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

EDIT: этот сниппл исправил его для меня:

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

Ответ 5

Временное решение для 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) }

Ответ 6

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

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

task 'assets:stub_mongoid' do
  def Mongoid.load!(*args)
    true
  end
end

Ответ 7

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

Ответ 8

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

Spork.trap_method

Ответ 9

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

Верно, что ответ на самый высокий рейтинг @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:[email protected]/dbname bundle exec rake assets:precompile

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

Ответ 10

Отключить AR:

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

ar = ActiveRecord::Base
def ar.establish_connection
end