Фрагменты Rails с наследованием одной таблицы

#ruby-on-rails

#ruby-on-rails

Вопрос:

Я хочу использовать partials в rails наряду с наследованием одной таблицы. В настоящее время у меня это работает:

 render partial: @vehicle

# which renders the relevant view, depending on object type, eg:
#   views/trucks/_truck.haml
#   views/car/_car.haml
  

Я хочу оставить эти представления по умолчанию на месте и создать дополнительное компактное представление для каждого объекта, возможно, вот так

 # example code only, I want to write something like:
render partial: 'compact', locals: {vehicle: @vehicle}

# and then have this render (for example) with
#   views/trucks/_compact.haml
#   views/car/_compact.haml
  

Я могу с радостью переименовывать объекты или изменять имена файлов или местоположения, но каков самый простой способ поддерживать два вида представлений (compact и default)?

Позже будет еще много классов, поэтому ищите очень чистый, элегантный код.

(rails 3.0.5 на ruby 1.9.2)

Комментарии:

1. возможно, мне следует использовать шаблоны вместо этого. просто ищу «правильный» путь rails.

Ответ №1:

Чтобы получить именно то, что вы просили, вы должны сделать это:

 render partial: "#{@vehicle.type.tableize}/#{@vehicle.type.underscore}", object: @vehicle
  

и вы получите визуализацию:

 views/trucks/_truck.html.haml
  

и объект будет доступен как:

 @truck
  

Комментарии:

1. render @vehicle дает тот же эффект. Объект доступен как truck внутри partial.

Ответ №2:

Возможно, есть способ получше, но всегда есть такой подход:

 render partial: "#{@vehicle.class.to_s.tableize}/compact", locals:{vehicle: @vehicle}
  

(или, возможно, это должно быть _compact , а не просто compact, но вы поняли идею)

Комментарии:

1. Нет, compact будет работать. Только имя файла должно иметь префикс подчеркивания. Одна из наиболее раздражающих ошибок Rails, imo :

Ответ №3:

Я сделал нечто подобное, но вместо того, чтобы размещать частичные файлы в двух отдельных файлах, я объединил их и использовал locals аргумент для передачи флага:

 # The hash syntax for render is redundant, you can simply pass your instance
# Render the long-form of your partial
render @vehicle

# When using render _instance_, the second argument becomes the locals declaration
# Render the compact form
render @vehicle, compact: true
  

И затем, в моем partial…

 <% if defined? compact %>
  <!-- HTML for compact view -->
<% else %>
  <!-- HTML for extended view -->
<% end %>
  

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

Недостатком является то, что это небольшое отклонение от «традиционного» использования partials.