Как мне использовать константы Ruby в представлениях Rails?

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

В моем user.rb файле есть следующая константа, которая используется для выпадающего меню выбора в одной из моих форм. Это сохраняет числовое значение.

На мой взгляд, когда я получу это сохраненное числовое значение, могу ли я использовать эту константу для извлечения соответствующего ей имени и его отображения? Или я должен создать отдельный массив, который занимается этим?

 LANGPROFICIENCY = [
  ["Elementary proficiency",           1],
  ["Limited working proficiency",      2],
  ["Professional working proficiency", 3],
  ["Full professional proficiency",    4],
  ["Native or bilingual proficiency",  5]
]
  

Ответ №1:

Во-первых, хэш — отличная отправная точка для такого рода данных. Вместо:

 LANGPROFICIENCY = [
  ["Elementary proficiency",           1],
  ["Limited working proficiency",      2],
  ["Professional working proficiency", 3],
  ["Full professional proficiency",    4],
  ["Native or bilingual proficiency",  5]
]
  

использовать:

 LANGPROFICIENCY = {
  "Elementary proficiency"           => 1,
  "Limited working proficiency"      => 2,
  "Professional working proficiency" => 3,
  "Full professional proficiency"    => 4,
  "Native or bilingual proficiency"  => 5
}
  

Вы можете использовать keys или values отдельно, если хотите, что делает это удобным, когда они вам нужны по отдельности, или вы можете выполнить поиск по ключу, чтобы найти значение, как всегда.

Оттуда вы можете изменить хэш:

 Hash[*LANGPROFICIENCY.to_a.map{ |a| a.reverse }.flatten]
  

которое вернет:

 {
  1 => "Elementary proficiency",
  2 => "Limited working proficiency",
  3 => "Professional working proficiency",
  4 => "Full professional proficiency",
  5 => "Native or bilingual proficiency"
}
  

упрощение обратного поиска.

Делая еще один шаг вперед, если вы знаете, что не будет столкновений, которых не должно быть:

 LANGPROFICIENCY = LANGPROFICIENCY.merge( Hash[ *LANGPROFICIENCY.to_a.map{ |a| a.reverse }.flatten ] )
  

что приводит к:

 {
  "Elementary proficiency"           => 1,
  "Limited working proficiency"      => 2,
  "Professional working proficiency" => 3,
  "Full professional proficiency"    => 4,
  "Native or bilingual proficiency"  => 5,
  1 => "Elementary proficiency",
  2 => "Limited working proficiency",
  3 => "Professional working proficiency",
  4 => "Full professional proficiency",
  5 => "Native or bilingual proficiency"
}
  

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

Я постоянно использую этот трюк или вариации на эту тему. Это позволяет очень легко отображать туда и обратно, используя одну переменную.

Теперь, если вы пробовали каждый шаг в IRB или Ruby, вы получите несколько предупреждений о « warning: already initialized constant LANGPROFICIENCY «. Ответ на этот вопрос заключается в использовании переменной вместо константы. Кроме того, LANGPROFICIENCY — это едва ли читаемое имя переменной. Я бы рекомендовал использовать lang_proficiency или что-то подобное.

Ответ №2:

Если вы хотите получить имя,

 LANGPROFICIENCY.rassoc(2)[0] #=> "Limited working proficiency"
  

Но если ваш массив должен иметь числовое значение в порядке возрастания, у вас здесь большая избыточность. Вместо того, что у вас есть, вы можете упростить это до:

 LANGPROFICIENCY = [
  "Elementary proficiency",
  "Limited working proficiency",
  "Professional working proficiency",
  "Full professional proficiency",
  "Native or bilingual proficiency"
]
  

и делать

 LANGPROFICIENCY[2-1] #=> "Limited working proficiency"
  

Комментарии:

1. интересно, спасибо. однако я получаю uninitialized constant ошибку в моем view…is мне нужно что-то сделать в моей модели, чтобы сделать это доступным для моего представления?

2. Вы должны определить константу перед ее вызовом. Итак, поместите LANG... = ранее в коде. Вы можете поместить это где-нибудь ранее в теле класса, где у вас есть методы, которые его вызывают. Если вы не собираетесь использовать это в модели, вы можете поместить это в представление.

Ответ №3:

LANGPROFICIENCY это массив массивов. Игнорируйте, что это константа, это просто означает, что вы не можете ее изменить.

 selected_entry = LANGPROFICIENCY.select {|entry| entry[1] == selected_id }

>> LANGPROFICIENCY = [["Elementary proficiency",1], ["Limited working proficiency",2], ["Professional working proficiency",3], ["Full professional proficiency",4], ["Native or bilingual proficiency",5]]
=> [["Elementary proficiency", 1], ["Limited working proficiency", 2], ["Professional working proficiency", 3], ["Full professional proficiency", 4], ["Native or bilingual proficiency", 5]]

>> selected_id = 3
=> 3

>> selected_entry = LANGPROFICIENCY.select {|entry| entry[1] == selected_id }                                                     
=> [["Professional working proficiency", 3]]

>> selected_entry.flatten
=> ["Professional working proficiency", 3]
  

Предположим, что выбранный вами индекс находится в selected_id и имеет значение 3:
Теперь у вас есть массив, соответствующий записи в LANGPROFICIENCY.

Комментарии:

1. Приношу извинения за форматирование. По какой-то причине я не смог заставить редактор нормально работать с блоками кода.

2. когда вы создаете ответ, вы можете нажать на оранжевую «?» в правом верхнем углу окна редактирования, чтобы получить советы по форматированию.

3. @железный дровосек, спасибо, я знаю… Я думаю, что состояние редактора было перепутано с вырезанием и вставкой.

Ответ №4:

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

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

 def proficiency_from_value value
  return LANGPROFICIENCY.flatten[2 * (value - 1)]
end
  

Комментарии:

1. Я думаю, что это должно быть LANGPROFICIENCY.flatten[2 * (value-1)]