Зачем нам нужно передавать: объект на частичные? - PullRequest
1 голос
/ 12 февраля 2011

У меня есть модель Категория has_many: подкатегории

Я использую код для заполнения раскрывающегося значения подкатегорий в соответствии со значением раскрывающегося списка категорий в представлении с использованием Ajax. Вот код:

_form.html.erb

<%= f.select :category_id, @categories, {}, :tab_index => 4, :onchange => "#{remote_function(:url  => {:action => "populate_subcategories"},
                                                   :with => "'category_id='+value")}" %>
<div id = "subcategories_div">
  <%= render :partial => "subcategories", :object => @subcategories %>
</div>

deals_controller.rb

def new
  @deal = Deal.new
  @categories = Category.all.map { |category| [category.name, category.id]}
  @subcategories = @categories.first.subcategories.map { |subcategory| [subcategory.name, subcategory.id] }
end

def populate_subcategories
  subcategories = Subcategory.where(:category_id => params[:category_id]).map { |subcategory| [subcategory.name, subcategory.id] }

  render :update do |page|
    page.replace_html 'subcategories_div', :partial => 'subcatgories', :object => subcategories
  end
end

и, наконец, _subcategories.html.erb

<%= f.select :subcategory_id, subcategories, {}, :tab_index => 5 %>

Мой вопрос в коде page.replace_html 'subcategories_div', :partial => 'subcatgories', :object => subcategories почему мы определяем подкатегории как локальные переменные и передаем их как объекты в частичные? Мы могли бы написать так

def populate_subcategories
  @subcategories = Subcategory.where(:category_id => params[:category_id]).map { |subcategory| [subcategory.name, subcategory.id] }

  render :update do |page|
    page.replace_html 'subcategories_div', :partial => 'subcategories'
  end
end

используйте @subcategories в качестве переменной экземпляра, чтобы она была доступна в частичном порядке, как в случае обычных представлений в Rails.

Также в _subcategories.html.erb

<%= f.select :subcategory_id, @subcategories, {}, :tab_index => 5 %>

и в _form.html.erb

<div id = "subcategories_div">
  <%= render :partial => "subcategories" %>
</div>

Почему первый метод предпочтительнее второго? Это потому, что у нас есть только одна переменная для передачи в частичное? Есть ли улучшение производительности для первого метода?

Ответы [ 2 ]

2 голосов
/ 12 февраля 2011

Причина в том, что вы хотите, чтобы ваши частичные коды не зависели от ваших представлений. Используя @subcategories, вы создаете зависимость между вашей частичной и вашей точкой зрения, которая не нужна. Это означает, что для повторного использования этого же частичного вы должны убедиться, что у вас определена @subcategories, а это может быть не так. Например, у вас могут быть только @my_subcategories или @filtered_subcategories. Хуже того, у вас могут быть @subcategories и @filtered_subcategories, и вы можете захотеть отобразить оба, используя один и тот же фрагмент. В этом случае лучше иметь возможность передавать ваши подкатегории в частичное, а не в зависимости от устанавливаемых переменных экземпляра. Таким образом, ваши частичные компоненты действительно модульные и соответствуют объектно-ориентированному принципу инкапсуляции.

Например:

<h1><%= My Subcategories %></h1>
render :partial => 'subcatgories', :object => @my_subcategories
<h1><%= Other Subcategories %></h1>
render :partial => 'subcatgories', :object => @other_subcategories
1 голос
/ 13 февраля 2011

вы можете изящно назвать свои ивары в частичках,

render 'subcatgories', :subcategories => @hashtags

или

render 'subcatgories', :subcategories => @legals

тогда вы можете использовать subcategories в своей части, используя ivar, как будто его имя претендует на

иди и посмотри ActionView :: Rendering # render

существует более длинная форма params для достижения того же поведения ... (:partial => 'subcatgories', :locals => {:subcategories => @hashtags})

Я считаю, что :subcategories => @hashtags имеет лучшую читаемость, чем :object => @hashtags

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...