Как я могу добавить путь просмотра к поиску частичного рендеринга Rails?

Я хотел бы иметь следующую структуру каталогов:

views/
  app1/
    users/_user.html.erb
    users/index.html.erb

  app2/
    users/index.html.erb

  shared/
    users/_user.html.erb
    users/index.html.erb

На мой взгляд, я бы назвал

# app1/users/index.html
<%= render :partial => "user" %>
# => /app1/users/_user.html.erb


# app2/users/index.html
<%= render :partial => "user" %>
# => /shared/users/_user.html.erb

В общем, как мне сказать Rails проверить каталог /app2/users, а затем общий каталог, прежде чем он выдаст ошибку об отсутствующем шаблоне?

Обновлять


Я обошел это (как предложил Сентил, используя File.exist?

Вот мое решение - отзывы и предложения приветствуются

# application_helper.rb

# Checks for a partial in views/[vertical] before checking in views/shared
def partial_or_default(path_name, options={}, &block)
  path_components         = path_name.split("/")
  file_name               = path_components.pop
  vertical_file_path      = File.join(vertical}, path_components, file_name)
  shared_file_path        = File.join("shared", path_components, file_name)
  full_vertical_file_path = File.join("#{Rails.root}/app/views/", "_#{vertical_file_path}.html.erb")
  attempt_file_path       = File.exist?(full_vertical_file_path) ? vertical_file_path : shared_file_path
  render({:partial => attempt_file_path}.merge(options), &block)
end

person bodacious    schedule 21.05.2011    source источник
comment
По какой причине вы не можете использовать File.exists? для проверки выхода файла и рендеринга соответствующего файла?   -  person sent-hil    schedule 21.05.2011


Ответы (1)


В рельсы уже встроено что-то, что облегчает вам этот тип «тематики». Он называется prepend_view_path.

http://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path

Также есть append_view_path для добавления путей в конец стека поиска.

У меня это успешно работает в производстве:

 class ApplicationController < ActionController::Base
   before_filter :prepend_view_paths

   def prepend_view_paths
     prepend_view_path "app/views/#{current_app_code}"
   end
 end

Теперь каждый контроллер будет сначала искать в "views/app1" (или как там окажется ваше динамическое имя) представления, соответствующие вызываемому действию.

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

person twmills    schedule 21.05.2011
comment
Это действительно потрясающе! Я бы хотел, чтобы у нас была эта реализация... кстати, это только что было описано в railscasts.269 (но ваш ответ уже все говорит) - person ecoologic; 06.06.2011
comment
Правильный URL: api.rubyonrails.org/classes/ActionController/Base.html# M000267 - person davidcollom; 29.11.2012
comment
Старый, но для этого есть метод класса вместо того, чтобы делать это с фильтром - person Carson Reinke; 20.11.2013
comment
Метод класса, о котором говорит Карсон, это AbstractController.prepend_view_path. - person lime; 15.04.2014
comment
Вы также можете использовать self.class.prepend_view_path в действиях вашего контроллера. - person Jeffrey Guenther; 31.08.2017