Как я могу свернуть этот очень повторяющийся код Ruby / Rails? - PullRequest
1 голос
/ 24 апреля 2009

У меня есть две небольшие структурные проблемы, которые я не знаю, как решить, учитывая мое относительное новичок в RoR.

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

<ul style="list-style-type: circle">
  <li><%= @apples.size %> apples</li>
  <li><%= @oranges.size %> oranges</li>
  <li><%= @bananas.size %> bananas</li>
  <li><%= @grapefruits.size %> grapefruits</li>
</ul>

Можно ли это реорганизовать так, чтобы мне нужно было только один раз повторить список фруктов разных видов, и автоматически генерировать соответствующие <li>? Редактировать: Я забыл добавить, что @apples, @oranges и т. Д. Могут быть nil. Есть ли идиоматический способ справиться с этим?

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

@apples = Apple.find(:all)
@apples.each { |apple| apple.do_stuff(:xyz) }

@bananas = Banana.find(:all)
@bananas.each = { |banana| banana.do_stuff(:xyz) }

# ... &c

Как видите, одна и та же операция вызывается много раз одним и тем же способом. Есть ли способ сократить это до что-то вроде [Apple.find(:all), ...].each { |fruit| ... } и вместо этого работать?

Большое спасибо за вашу помощь!

Ответы [ 3 ]

5 голосов
/ 24 апреля 2009

Я бы сделал это в качестве помощника

def fruit_size(fruit)
  list = @fruits[fruit]
  return if list.empty?

  content_tag(:li, "#{list.size} #{fruit}")
end

И это в виде:

<% ["apples", "oranges", "bananas", .....].each do |fruit| %>
  <%= fruit_size(fruit)
<% end %>

В вашем контроллере:

@fruits = {}
["apples", "oranges", "bananas", ......].each do |fruit|
  @fruits[fruit] = fruit.classify.constantize.find(:all).each {|record|
    record.whatever_here
  end
end

Имеет смысл хранить все элементы в хэше, @fruits, чтобы вам не приходилось использовать instance_variable_get и прочее.

Возможно, вы также хотите определить этот массив где-нибудь, чтобы вам не приходилось повторять его в контроллере и в представлении. Давайте представим, что у вас есть фруктовая модель.

class Fruit < ActiveRecord::Base
  FRUITS = ["apples", "oranges", "bananas", ....]
end

Затем используйте Fruit :: FRUITS в представлении и контроллере.

0 голосов
/ 24 апреля 2009

Вы можете сделать это довольно просто.

В вашем контроллере:

def whatever
  @fruits = {
    :apples => Apple.find(:all).each{ |a| a.do_stuff(:xyz) }, 
    :bananas => Banana.find(:all).each{ |a| a.do_stuff(:xyz) } # ... 
  }
end

На ваш взгляд:

<% @fruits.each |k, v| %>
  <li><%= v.nil? ? 0 : v.size %> <%= k.to_s %></li>
<% end %>

Хотя вы можете решить, является ли do_stuff чем-то, что можно сделать с помощью более сложного искателя или с помощью именованной области.

0 голосов
/ 24 апреля 2009

Для первой части:

    @li = ''
    [@apples, @oranges, @bananas, @grapefruit].each{|fruit| 
       @li << "<li>#{fruit.size}</li>"}

    <ul style="list-style-type: circle">
    <%=@li%>
    </ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...