Подтвердить что ты не робот

Rails - значение по умолчанию в текстовом поле, но только для new_record?

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

В настоящее время у меня есть:

<% if @content.new_record? %>
  <%= f.text_field :slug, :value => "#{generate_slug(6)}" %>
<% else %>
  <%= f.text_field :slug %>
<% end %>

Но это кажется немного многословным. Это лучший способ, иначе нет другого пути? (Rails newb просто пытается найти "Rails way" по вопросам, которые я не уверен)


Edit

Я должен заметить, что помощник в настоящее время находится в /app/helpers/application _helper.rb Перемещено как частное действие в контроллере содержимого. Дэвид ответил отлично.

4b9b3361

Ответ 1

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

@content.slug ||= generate_slug(6)

Это присваивает значение атрибуту slug, если ни один из них не присутствует

Затем, на ваш взгляд, вы можете просто использовать

<%= f.text_field :slug %>

Ответ 2

Функции

  • Попробуйте after_initialize обратный вызов в вашей модели.
  • Попробуйте создать метод в своей модели, где вы устанавливаете значения по умолчанию и вызываете его в своем новом действии в контроллере. Также вызывается этот метод, если ваш файл не работает, и вы создаете новый. Не забудьте установить значение по умолчанию только в том случае, если не существует никакого значения с помощью оператора || =.

Пример. Я набираю телефон!

Ответ 3

Я использую jQuery в своих проектах, поэтому, когда мне нужна такая функциональность, я обычно использую что-то вроде labelify. Тогда я бы использовал что-то вроде <%= f.text_field :slug, :title => generate_slug(6) %>. (Горячий совет, вам не нужно помещать вызов #generate_slug внутри строки, если он возвращает что-то, что будет разрешено для самой строки, на самом деле это более эффективно, если вы этого не делаете.)

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

def Content < ActiveRecord::Base
  def slug
    self.new_record? ? self.slug_for_new_record : attributes[:slug]
  end

  private
  def slug_for_new_record
    # I don't know what you're doing in generate_slug, but it sounds model-
    # related, so if so, put it here and not in a helper
  end
end

Если это действительно относится к представлению, еще один вариант - просто сделать ваш Ruby немного более кратким (вам придется судить, насколько это более читаемо):

<%= f.text_field :slug, :value => (generate_slug(6) if @content.new_record?) %>

Не забывайте, что parens окружают (generate_slug(6) if @content.new_record?). Если вы это сделаете, if будет применен к текстовому полю, которое вам не подходит.

Но есть еще много способов сделать это. Вышеупомянутая строка кода невелика, если ваша логика может измениться, и вы вставляете этот код по всему проекту rails. Когда я захотел добавить "обязательный" класс в свои текстовые поля, но только если они были новой записью (у нас были некоторые устаревшие данные, которые мы не хотели очищать), я создал свой собственный построитель форм с required_field, который только что назвал text_field, и добавил класс "required", если элемент был новой. Это может показаться работой, но у нас есть около 20 различных форм, каждый из которых имеет потенциально несколько обязательных полей, и намного проще изменить бизнес-логику в одном месте. Поэтому, если вы действительно думаете, что эта логика принадлежит взгляду, но у вас тонна этих строк кода, и вы не хотите менять ее в миллионах мест, тогда FormBuilder - это путь. Я думаю, что это в большинстве случаев красивее и уместнее, чем помощник, но опять же, красота в глазах смотрящего. Здесь мой код несколько адаптирован для вашего случая:

# config/environment.rb
ActionView::Base.default_form_builder = NamespacesAreFun::FormBuilder

# lib/namespaces_are_fun/form_builder.rb
module NamespacesAreFun
  class FormBuilder < ActionView::Helpers::FormBuilder
    def slug_field(method, options = {})
      opts = options.to_options
      opts.merge!(:value => generate_slug) if self.object.new_record?
      text_field(method, opts)
    end
  end
end

# views/.../your_view.html.erb
<%= f.slug_field :slug %>

Надеемся, что во всех этих разных подходах вы найдете подходящий проект.