Для направляющие 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>
Сохраните состояние Задачи в дб, таким образом, что значения легко локализуемы, т.е. я не уверен, что хочу сохранить "нормальный", "активный", "завершенный" как строковое поле.
Решение должно работать с направляющими 3.0.
Я должен сохранить поле как целое число (см. выше)? Если так, как я отображаю корректное человекочитаемое состояние в HTML-таблице в моем представлении Rails, например, шоу, "Активное" вместо "1" в HTML-таблице.
Я должен использовать перечисление? Если так, действительно ли это легко локализовать позже?
Если я использую прямые строки, например, "Нормальный", "Активный", "Завершенный"
Можно ли предоставить быстрый пример кода помощника представления, контроллера или просмотреть ли код для создания этой работы?
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 ','}"
Проще всего было бы просто сохранить фактические строки в поле вместо добавления еще одной таблицы. В зависимости от вашей точки зрения это либо плохая идея, поскольку ваша база данных не будет достаточно нормализована, либо отличная идея, поскольку ваше приложение теперь более эффективно для нормализации.
Если вы решите не делать этого и сохранить значения в отдельной таблице; вам необходимо настроить отношения в модели.
class Task < ActiveRecord::Base
has_one :status
end
class Status < ActiveRecord::Base
belongs_to :tasks
end
Затем в вашем представлении вы можете ссылаться на значение следующим образом:
<%= task.status %>
Я использовал 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, этот плагин - хороший выбор.
Я предпочитаю хранить "нормальный", "активный", .. "завершенный" как строку в таблице, потому что:
В наши дни я склонен разделять Максимально возможное количество констант Rails из базы данных. Вокруг нас всегда есть специалисты по PHP / MSSQL / ?? DBA (которые могут не любить Rails так сильно, как мы; -)
Итак, ответ - не целое число или перечисление (а varchar; -)