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

Rails 4 + append_view_path

Я хочу использовать динамический путь в моем контроллере в rails gem.

Я добавил в

module MyGem
  class FooController < Config.controller
    before_action ->{ append_view_path "app/views/my_gem/#{wizard_name}" }
...

и в представлениях мне нужно указать путь как

app/views/my_gem/#{wizard_name}/my_gem/foo/some.erb

находится в Rails каким-то образом, чтобы разрезать относительный путь пространства имен gem и получить путь поиска, например?

app/views/my_gem/#{wizard_name}/some.erb
# or
foo/bar/some.erb

Спасибо!

UPD:

Я понимаю, что есть способ отключить isolate_namespace в Engine, но я считаю, что это не лучший и единственный вариант.

UPD2: для Rails4 эта идея была очень полезной https://coderwall.com/p/p_yelg/render-view-outside-of-a-controller-in-rails-4

4b9b3361

Ответ 1

В геме Devise есть способ добавления пути поиска представлений путем переопределения метода _prefixes:

class DeviseController < Devise.parent_controller.constantize
  include Devise::Controllers::ScopedViews

  # Override prefixes to consider the scoped view.
  # Notice we need to check for the request due to a bug in
  # Action Controller tests that forces _prefixes to be
  # loaded before even having a request object.
  #
  # This method should be public as it is is in ActionPack
  # itself. Changing its visibility may break other gems.
  def _prefixes #:nodoc:
    @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
      ["#{devise_mapping.scoped_path}/#{controller_name}"] + super
    else
      super
    end
  end

end

Может ли это быть применено к вашему варианту использования?

Смотрите источник:
https://github.com/plataformatec/devise/blob/master/app/controllers/devise_controller.rb

Ответ 2

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

Ответ 3

Вы можете сделать свой способ визуализации, который читает произвольный файл, интерпретировать ERB и отображать его как HTML-страницу, например.

ERB.new(File.read(Rails.root.join('foo', bar', 'some.erb'))).result(binding)

Передавая binding, шаблон будет иметь доступ ко всем переменным в текущем контексте.

Подробнее см. документы ERB: http://apidock.com/ruby/ERB

Ответ 4

Предполагая, что ваш драгоценный камень является движком, вы можете просто вызвать render :some из них. Если приложение имеет представление с именем <gem_name>/<controller_name>/some.html.erb оно будет использовано.

Кроме того, вы можете предоставить версию этого представления в своем геме, которая будет использоваться, если приложение еще не предоставило ее.

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

Таким образом, в вашем контроллере gem вы должны написать render "#{wizard_name}/some" и он будет искать этот вид как в нашем приложении app/views/<gem_name>/<controller_name>/<wizard_name>/some.html.erb и в вашем app/views/<controller_name>/<wizard_name>/some.html.erb gem app/views/<controller_name>/<wizard_name>/some.html.erb.