Ответ 1
В вашем контроллере
@content.slug ||= generate_slug(6)
Это присваивает значение атрибуту slug
, если ни один из них не присутствует
Затем, на ваш взгляд, вы можете просто использовать
<%= f.text_field :slug %>
В модели содержимого есть атрибут с именем 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 Перемещено как частное действие в контроллере содержимого. Дэвид ответил отлично.
В вашем контроллере
@content.slug ||= generate_slug(6)
Это присваивает значение атрибуту slug
, если ни один из них не присутствует
Затем, на ваш взгляд, вы можете просто использовать
<%= f.text_field :slug %>
Функции
Пример. Я набираю телефон!
Я использую 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 %>
Надеемся, что во всех этих разных подходах вы найдете подходящий проект.