Какой способ загрузить другие коллекции моделей для нового, отредактировать обновление и создать действия? - PullRequest
1 голос
/ 28 ноября 2010

Как лучше всего загрузить модель категории, для ProductController в новом, отредактировать обновление и создать действия

Товар имеет коллекцию категорий

class Product < ActiveRecord::Base
  has_many :categories
end 

Всегда для новых действий, редактирования, создания и обновления, мне нужно загружать коллекцию категорий для заполнения списка check_box_tag

"шаги ребенка" для этой ситуации:

class Admin::ProductsController < Admin::AdminApplicationController

 def new
   @product = Product.new
   @categories = Category.all
 end

 def edit
   @product = Product.find(params[:id])
   @categories = Category.all
 end

 def create
   @product = Product.new(params[:product])
   if @product.save
     flash[:notice] = 'Product was successfully created'
     redirect_to edit_admin_product_path(@product)
   else
     @categories = Category.all
     render :new
  end
 end

 def update
   @product = Product.find(params[:id])
   @product.update_attributes(params[:product])
   if @product.save
     flash[:notice] = 'Product was successfully updated'
     redirect_to edit_admin_product_path(@product)
   else
     @categories = Category.all
     render :edit
   end
 end
end 

Я не хочу всегда загружать Category.all в разных ситуациях для одной и той же цели

Опции:

Первый - загрузить категории над видом:

<% Category.all.each do |cat| %>
  <li>
    <%= check_box_tag .... %>
  </li>
<% end %>

/

Второе - категории загрузки через ProductsHelper:

module ProductsHelper

  def categories
   Category.all
  end

end

/

"Третий" - существует ли фильтр типа 'before_render'?

class Admin::ProductsController < Admin::AdminApplicationController

  before_render :load_categories :edit, :new

  def load_categories
    @categories = Category.all
  end

end

: D: D: D

Каковы пути для этой ситуации?

С наилучшими пожеланиями, Пабло Кантеро

Ответы [ 3 ]

1 голос
/ 29 ноября 2010

В вашем контроллере или, если необходимо, в другом месте, в application_controller.rb:

def all_categories
  @all_categories ||= Category.all
end
helper_method :all_categories

При первом вызове он попадет в БД, а затем вернет переменную экземпляра контроллера.

0 голосов
/ 28 ноября 2010

Я бы предпочел ваше третье решение.Мне не нравится использовать бизнес-логику в представлении, потому что я полагаю, что сбор информации является задачей контроллера, а на уровне представления я просто хочу использовать данные и вспомогательные методы.Использование Category.all в слое представления может быть полезно при использовании кэша, но в этом случае вам следует как-то отправить сигнал с истекшим сроком, если он изменился.

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

0 голосов
/ 28 ноября 2010

Я бы выбрал первый вариант в этом случае.

Редактировать

Как я уже упоминал в комментариях, это зависит от ситуации. Для меня относительно чистым способом было бы определить метод categories в контроллере и объявить его вспомогательным. Затем назовите это, когда вам это нужно в представлении.

Однако (и это та ситуация, которую я предусмотрел при первом ответе), если бы это было одно поле формы, я бы просто вызвал модель из представления просто для простоты - методы типа

helper_method :all_categories
private
def all_categories
  Category.all
end

не самый элегантный код.

...