ruby helpers для создания текста представлений вокруг ассоциаций

Я не уверен, как это называется, но у меня есть модель a, которая has_many b. При отображении некоторой модели a в представлении я хотел бы напечатать некоторый текст, описывающий все ассоциации модели b, которые он имеет, например:

«Имеет связь с foo, bar, baz и ## еще…»

foo, bar, baz — имена трех мобделей b. И я не хочу печатать все имена, если их больше 3, поэтому я хочу закончить их с оставшимся балансом # ассоциаций.

Я могу сделать это программно в ruby, но мне было интересно, существуют ли какие-то вспомогательные методы, которые могут сделать это для меня.

Спасибо.


person deruse    schedule 10.07.2011    source источник


Ответы (2)


Версия с проверкой диапазона + необязательный блок для преобразования элементов в строку:

def enumerate_as_text(seq, max, &block)
  text = seq.first(max).map { |itm|
    block_given? ? yield(itm) : itm.to_s
  }.join(", ")
  text += ", and #{seq.length - max} more" if max < seq.length
  text
end

Тестовый забег:

blob = %w{a b c d e f g h i j}

puts blob.length
puts blob.join(", ")
puts enumerate_as_text(blob, 1)
puts enumerate_as_text(blob, 4)
puts enumerate_as_text(blob, 9)
puts enumerate_as_text(blob, 10)
puts enumerate_as_text(blob, 11)
puts enumerate_as_text(blob, 20) { |itm| "itm: #{itm}" }

Выход:

10
a, b, c, d, e, f, g, h, i, j
a, and 9 more
a, b, c, d, and 6 more
a, b, c, d, e, f, g, h, i, and 1 more
a, b, c, d, e, f, g, h, i, j
a, b, c, d, e, f, g, h, i, j
itm: a, itm: b, itm: c, itm: d, itm: e, itm: f, itm: g, itm: h, itm: i, itm: j
person Casper    schedule 10.07.2011
comment
это не отвечает на вопрос: как он мог автоматически получать ассоциации? - person apneadiving; 10.07.2011
comment
Часть ответа должна была заключаться в использовании reflect_on_all_associations - person apneadiving; 10.07.2011

Я не вижу способа сделать это легко, и код ruby/rails для его получения довольно прост. Так почему бы не сделать вспомогательный метод самостоятельно? Подпись для вашего метода может быть:

def truncate_models(models, numbers)
  models[0..numbers-1].map{|m| m.name}.join(", ") + "and #{models.size - numbers} more..."
end

Итак, позвонив (по-HAML)

.models
  Has an association with
  = truncate_models(models, 3) 

вы должны получить то, что хотите.

person mliebelt    schedule 10.07.2011
comment
это не отвечает на вопрос: как он мог автоматически получать ассоциации? - person apneadiving; 10.07.2011
comment
Часть ответа должна была заключаться в использовании reflect_on_all_associations - person apneadiving; 10.07.2011
comment
@apneadiving, когда я прочитал вопрос, dhruvg знает, что все три или более вещей относятся к классу B, модель a has_many b. dhruvg не ищет все ассоциации всех типов и поэтому не нуждается в reflect_on_all_associations. Это ответ на вопрос, который не задают. - person Ray Baxter; 11.07.2011
comment
@Ray Baxter: ИМХО, я думаю, он хочет вернуть то, что внутри модели. В любом случае, пусть говорит спрашивающий: я не ставил -1. - person apneadiving; 11.07.2011