В направляющих, как я должен реализовать поле Status для приложения Задач - целое число или перечисление?

Для направляющие 3.0 приложения Todo, у меня есть модель Tasks с полем Status. Что лучший способ состоит в том, чтобы хранить данные поля Status (тип поля) и все еще отобразить человекочитаемую версию в представлении (HTML-таблица)? Состояние может быть:

0 = Нормальный
1 = Активный
2 = Завершенный

Прямо сейчас у меня есть это:

Схема направляющих здесь:

create_table "задачи": вызовите => верный, делают |t |
t.integer "состояние": ограничьте => 1: значение по умолчанию => 0: пустой указатель => ложь

Модель направляющих здесь:

class Task < ActiveRecord::Base
  validates_inclusion_of :status, :in => 0..2,
    :message => "{{value}} must be 0, 1, or 2"

Представление направляющих здесь:

<h1>Listing tasks</h1>

<table>
  <tr>
    <th>Status</th>
    <th>Name</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @tasks.each do |task| %>
  <tr>
    <td><%= task.status %></td>
    <td><%= task.name %></td>
    <td><%= link_to 'Show', task %></td>
    <td><%= link_to 'Edit', edit_task_path(task) %></td>
    <td><%= link_to 'Delete', task, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

Требования

  1. Сохраните состояние Задачи в дб, таким образом, что значения легко локализуемы, т.е. я не уверен, что хочу сохранить "нормальный", "активный", "завершенный" как строковое поле.

  2. Решение должно работать с направляющими 3.0.

Вопросы:

  1. Я должен сохранить поле как целое число (см. выше)? Если так, как я отображаю корректное человекочитаемое состояние в HTML-таблице в моем представлении Rails, например, шоу, "Активное" вместо "1" в HTML-таблице.

  2. Я должен использовать перечисление? Если так, действительно ли это легко локализовать позже?

  3. Если я использую прямые строки, например, "Нормальный", "Активный", "Завершенный"

  4. Можно ли предоставить быстрый пример кода помощника представления, контроллера или просмотреть ли код для создания этой работы?

32
задан Doug 16 April 2010 в 05:49
поделиться

4 ответа

1. Это зависит от того, насколько вы хотите оптимизировать запросы к БД.

2. Не совсем, он не поддерживается «из коробки» в AR. # Начиная с Rails 4 перечисления поддерживаются из коробки .

3.IMHO, вы можете использовать строки без большого снижения производительности (просто не забудьте добавить поле в индекс). Я бы сделал это, потому что это легче интернационализировать и поддерживать. Однако вы можете использовать целые числа, если вам нужна дополнительная производительность.

Вы можете взглянуть на 2 темы SO здесь и здесь , где это обсуждается.

4. Если вы хотите сохранить их как целые числа, вот как вы можете это сделать:

class Task << AR::Base
  NORMAL    = 1
  ACTIVE    = 2
  COMPLETED = 3


  STATUSES = {
    NORMAL    => 'normal',
    ACTIVE    => 'active',
    COMPLETED => 'completed'
  }

  validates_inclusion_of :status, :in => STATUSES.keys,
      :message => "{{value}} must be in #{STATUSES.values.join ','}"

  # just a helper method for the view
  def status_name
    STATUSES[status]
  end
end

и в поле зрения:

<td><%= task.status_name %></td>

Если вы хотите использовать строки, это будет проще:

STATUSES = ['normal', 'active', 'completed']
validates_inclusion_of :status, :in => STATUSES,
          :message => "{{value}} must be in #{STATUSES.join ','}"
43
ответ дан 27 November 2019 в 20:42
поделиться

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

Если вы решите не делать этого и сохранить значения в отдельной таблице; вам необходимо настроить отношения в модели.

class Task < ActiveRecord::Base
    has_one :status
end

class Status < ActiveRecord::Base
    belongs_to :tasks
end 

Затем в вашем представлении вы можете ссылаться на значение следующим образом:

<%= task.status %>
6
ответ дан 27 November 2019 в 20:42
поделиться

Я использовал Enum-Column для таких случаев использования. Плагин позволяет вам определять тип столбца перечисления в вашем сценарии миграции и создает тип столбца перечисления MYSQL для атрибута.

create_table :tasks do |t|
  ...
  t.enum :status, :limit => [:normal, :active, :completed], :default => :normal
  ...
end

Теперь в вашем коде вы можете делать следующее:

task.status = "active"
task.status = :completed
p "Task status: #{task.status}" # prints Task status: completed


Task.find_by_status(:active)
Task.find_by_status("active")
Task.find_by_status(2)

Также хорошо работает с сериализацией:

task.to_xml # will result in status= active instead of status-2

Другой приятный аспект заключается в том, что значения состояния отображаются в виде строк при просмотре с помощью обычного клиента БД (например: mysql command console или phpMyAdmin)

Плагин обеспечивает оптимальное хранение и удобный доступ для типов перечисления.

Предупреждение:

Плагин довольно старый и не поддерживается. Я широко использую его с MySQL DB. Мне пришлось исправить код, чтобы он работал на PostgreSQL. Если вы используете MySQL, этот плагин - хороший выбор.

3
ответ дан 27 November 2019 в 20:42
поделиться

Я предпочитаю хранить "нормальный", "активный", .. "завершенный" как строку в таблице, потому что:

  • это самодокументация (например, кто-то может просматривать данные, но никогда не читать исходный код Rails)
  • есть небольшое (если не совсем) снижение производительности
  • (все еще) легко сделать i18n с помощью виртуального атрибута Rails в модели или любого другого уровня в других языках.

В наши дни я склонен разделять Максимально возможное количество констант Rails из базы данных. Вокруг нас всегда есть специалисты по PHP / MSSQL / ?? DBA (которые могут не любить Rails так сильно, как мы; -)

Итак, ответ - не целое число или перечисление (а varchar; -)

2
ответ дан 27 November 2019 в 20:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: