2014-09-23 8 views
2

В моем приложении Rails, у меня есть следующие ассоциации:«Скажи, не спрашивай» при сохранении разделения проблем

  • Видео принадлежит Жанр(Видео не должны иметь жанр)
  • Жанр имеет много Видео(Жанр не может иметь видео)

В модели видео у меня есть следующий метод.

# models/video.rb 
def genre_name 
    genre.present? ? genre.name : '' 
end 

Это, чтобы избежать чего-то вроде этого в представлении (который только кажется грязным):

# views/videos/show.html.erb 
<% if @video.genre.present? %> 
    <%= @video.genre.name %> 
<% else %> 
    No Genre Present 
<% end %> 

Вместо этого, я могу это сделать (что выглядит намного опрятнее)

# views/videos/show.html.erb 
<%= @video.genre_name %> 

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

ответ

2

Если вы нашли себя делать такого рода вещи много, это может быть стоит посмотреть в узор декоратора, который может содержать такую ​​логику просмотра. (Я очень люблю использовать Draper для этой цели, но это не очень трудно свернуть свою собственную наивную реализацию.)

Затем ваш декоратор логик может выглядеть следующим образом:

class VideoDecorator def genre_name object.genre.try(:name).presence || "Fallback" end end

Вы можете обернуть модель в декораторе, как вы оказываете в контроллере:

@video = Video.find(params[:id]) 
respond_with @video.decorate 

И ваш взгляд «логика» (или его отсутствие) может выглядеть следующим образом приложения-широким:

<%= @video.genre_name %> 

Thoughtbot имеет превосходное объяснение шаблона декоратора here

+0

Мне это нравится, поскольку он удаляет метод genre_name из видеомодуля. –

+0

Пойти с этим методом. :) благодаря –

2

Вы могли бы написать на ваш взгляд

<%= @video.genre.try(:name) || 'No Genre Present' %> 

Если вам не нужен текст резервный, только

<%= @video.genre.try(:name) %> 

Read more about Object#try here.

Если вы хотите запасной вариант также когда name пустая строка (не только nil), вы можете использовать Object#presence

<%= @video.genre.try(:name).presence || 'No Genre Present' %> 
+0

Это очень приятно. Мне особенно нравится первый пример :) Спасибо. –

+0

Интересно, однако, если есть способ сделать это, не введя логику в представление? –

 Смежные вопросы

  • Нет связанных вопросов^_^