Как сохранить ассоциацию ActiveRecord DRY? - PullRequest
5 голосов
/ 17 октября 2008

У меня проблема с попыткой сохранить AR finders DRY в моем приложении. Я создал приложение для ведения блога, которое выбирает все связанные страницы, записи, ссылки, теги и категории для блога, когда пользователь впервые просматривает его. Пример действия шоу для контроллера блога показан ниже:

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]=@user.login
    render :layout=>false
  end

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

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

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

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

1 Ответ

3 голосов
/ 17 октября 2008

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

class BlogsController < ApplicationController
  def show
    session[:found_user]=@user.login
    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.

...