Как сохранить ассоциацию ActiveRecord DRY?

У меня проблема с попыткой сохранить СУХИЕ средства поиска AR в моем приложении. Я создал приложение для ведения блога, которое извлекает все связанные страницы, сообщения, ссылки, теги и категории для блога, когда пользователь впервые просматривает его. Пример действия show для контроллера Blog показан ниже:

def show
    #find blog by user name
    @user= User.find_by_login(params[:id])
    @blog= @user.blog
    @posts = Post.status("publish",@user).find(:all, :order => "created_at DESC")
    @tags = @user.tags
    @pages = Page.status("publish",@user).find(:all, :order => "created_at DESC")
    @links = @user.links.public_link.find(:all, :order => 'created_at DESC')
    @archives = @posts.group_by(&:month)
    @categories = @user.categories.group_by(&:name)
    session[:found_user][email protected]
    render :layout=>false
  end

Как вы можете видеть, это не очень СУХОЕ, так как есть другие действия, которые вызывают те же переменные экземпляра, такие как @tags и т. д. дальше в контроллере.

Как я могу сделать это более СУХИМ? Я попытался переместить его в модель блога, но мне все еще нужно вызывать в контроллере различные переменные экземпляра, такие как @tags и т. д.

Есть ли способ сохранить все эти переменные при первом вызове блога и повторно использовать их в контроллерах и действиях?

Спасибо за любой совет. Я использую Рельсы 2.1


person Community    schedule 16.10.2008    source источник
comment
Вау, я думаю, у тебя проблемы с шифтом.   -  person Node    schedule 17.10.2008
comment
Серьезно. Ваш вопрос режет мои уши.   -  person Bob Cross    schedule 17.10.2008


Ответы (1)


Я где-то читал в блоге, чтобы просто заменить перед фильтрами (или загрузить все виды данных в методе контроллера) вспомогательными методами. Что-то вроде этого:

class BlogsController < ApplicationController
  def show
    session[:found_user][email protected]
    render :layout=>false
  end

  helper_method :user, :blog, :posts, :tags, :pages, :links, :archives, :categories

  protected
  def user
    @user ||= User.find_by_login(params[:id])
  end

  def blog
    @blog ||= user.blog
  end

  def posts
    @posts ||= Post.status("publish", user).find(:all, :order => "created_at DESC")
  end

  def tags
    @tags ||= user.tags
  end

  def pages
    @pages ||= Page.status("publish", user).find(:all, :order => "created_at DESC")
  end

  def links
    @links ||= user.links.public_link.find(:all, :order => 'created_at DESC')
  end

  def archives
    @archives ||= posts.group_by(&:month)
  end

  def categories
    @categories ||= user.categories.group_by(&:name)
  end
end

## app/views/blogs/show.html.erb
<p>Name: <%=h user.name %></p>
<h3><%= posts.length %> Posts</h3>
<% posts.each do |post| %>
  ...
<% end %>
<ul>
  <% categories.each do |category| %>
    <li><%=h category %></li>
  <% end %>
</ul>

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

При необходимости абстрагируйте вспомогательные методы в модуль и включите модуль в ApplicationController.

person François Beausoleil    schedule 16.10.2008