简体   繁体   中英

Rails: using partials for inputs is correct?

I'm building a Rails app. I've done all the logic (db, controllers, models, etc). Now its time to make it nice.

In order to centralize the view of the app I was thinking in creating partials for the common stuff. For example one partial called common/_text_input.html.erb that will contain

<div class="field">
    <%= f.label id %><br />
    <%= f.text_field id %>
</div>

This will be called from inside a form using

<%= render partial: "common/text_input", locals: { f: f, id: :name } %>
  1. Is this approach correct? Is there any other option in rails to do this?

  2. If this is the correct way to do this, how can I acchieve this for a form tag, for example (where content is inserted inside it)?

Thanks

1 - There is another option to do this, Helpers and content_tag :

def text_input(form_builder, attribute, options = {})
  options = { div: { class: :field }, label: { class: attribute } }.merge(options) # default options

  content_tag :div, options[:div] do
    f.label(attribute, options[:label]) + content_tag(:br) + f.text_field(attribute, options[:input])
  end
end

Usage:

= form_for @resource do |f|
  = text_input(f, :first_name)
  = text_input(f, :last_name, input: { style: 'color: red;' }, label: { class: :another_class })

2 - It is correct to do with partials, but it is not as flexible as the Helpers are (see the options hash and the possibility to use another method in specific cases). To handle the form_tag (ie no form_builder ), you can implement a new method:

# usage
= form_tag root_path, method: :get do
  = text_input(nil, :search, input: { value: params[:search] }, label: { content: "Search for something!" })

# helper methods
def text_input(form_builder, attribute, options = {})
  options = { div: { class: :field }, label: { class: attribute } }.merge(options) # default options
  return text_input_tag(attribute, options) if form_builder.blank?

  content_tag :div, options[:div] do
    f.label(attribute, options[:label]) + content_tag(:br) + f.text_field(attribute, options[:input])
  end
end

def text_input_tag(attribute, options = {})
  value = options[:input].try(:delete, :value)
  label_content = options[:label].try(:delete, :content)

  content_tag :div, options[:div] do
    label_tag(attribute, label_content, options[:label]) + content_tag(:br) + text_field_tag(attribute, value, options[:input])
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM