Search code examples
ruby-on-railsformtastic

Conforming Rails form into Formtastic Equivalent


I have a Rails application where I am using Active Admin as the backend. Active Admin uses Formtastic and I am having trouble converting one of the input fields in my _form.html.erb for posts.

Here is the form...

<div class="container">
<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :author %>
    <%= f.collection_select :blog_id, Blog.all, :id, :name, prompt: "Select a blog" %>        
  </div>
  <div class="field">
    <p>
      Categories:<br>
      <%= hidden_field_tag "post[category_ids][]", nil %>
      <% Category.all.each do |category| %>
        <%= check_box_tag "post[category_ids][]", category.id, @post.category_ids.include?(category.id), id: dom_id(category) %> 
        <%= label_tag dom_id(category), category.name %>
      <% end %>    
    </p>
  </div>
  <div class="field">
    <%= f.hidden_field :status, value: "Draft" %> 
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body, class: "redactor", id: "redactor" %>
  </div>
  <div class="field">
    <%= f.label :published_on %><br />
    <%= f.date_select :published_on %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
</div>

Here is the portion that I am having trouble converting to formtastic specific code. It comes from Ryan's screencast on HABTM Checkboxes.

<div class="field">
    <p>
      Categories:<br>
      <%= hidden_field_tag "post[category_ids][]", nil %>
      <% Category.all.each do |category| %>
        <%= check_box_tag "post[category_ids][]", category.id, @post.category_ids.include?(category.id), id: dom_id(category) %> 
        <%= label_tag dom_id(category), category.name %>
      <% end %>    
    </p>
  </div>

Here is the formcode that is in the admin/post.rb file for Active Admin. If I use this I continue to get a no method error for category. I know that the way it is currently listed is incorrect.

form do |f|
    f.inputs "Details" do
        f.input :blog, hint: "Select a blog"
        f.input :title, hint: "Enter blog post title"
        f.input :published_on, as: :date, include_blank: false, hint: "Select a date", :prompt => {:day => "Day", :month => "Month", :year => "Year"}, :start_year => Time.now.year
        f.input :status, as: :select, collection: ["Draft", "Published"], include_blank: false, hint: 'Select "Draft" to save and post later, and "Publish" to post now'

        f.input :categories, as: :check_boxes

        f.input :body, input_html: { class: "redactor", id: "redactor" }
    end
    f.buttons
end

If anyone has any input I am most appreciated. I have looked at the formtastic documentation and watched Ryan's screencasts, but am still having issues converting.

Thanks!

EDIT: ABLE TO RESOLVE-SOLUTION BELOW

I was able to make this work after getting a little more familiar with Formtastic and Active Admin. Below is the relevant code in the form, show, and index views in Active Admin.

ActiveAdmin.register Post do
index do
    column "Post Title", :title
    column :blog
    column :published_on
    column :status
    column "Category", :categories do |post|
        post.categories.collect { |cat|  cat.name }.join(", ")
    end
    default_actions
end 

show do
    h5 "Created by #{post.blog.name} on #{post.created_at.strftime('%B %-d, %Y')}"
    h5 "Categories: #{post.categories.collect { |cat|  cat.name }.join(", ")}"
    h5 "Current Status: #{post.status}"
    h5 "Published On Date: #{post.published_on.strftime('%B %-d, %Y')} - (will only be posted if marked with Publish as status)"
    div do
        simple_format post.body
    end
end

form do |f|
    f.inputs "Details" do
        f.input :blog, hint: "Select a blog"
        f.input :title, hint: "Enter blog post title"
        f.input :published_on, as: :date, include_blank: false, hint: "Select a date", :prompt => {:day => "Day", :month => "Month", :year => "Year"}, :start_year => Time.now.year
        f.input :status, as: :select, collection: ["Draft", "Published"], include_blank: false, hint: 'Select "Draft" to save and post later, and "Publish" to post now'
        f.input :categories, as: :check_boxes, collection: Category.all
        f.input :body, input_html: { class: "redactor", id: "redactor" }
    end
    f.buttons
end  
end

Solution

  • I was able to construct the Formtastic version as shown below. It took a little more understanding of Formtastic and then making minor adjustments for Active Admin.

    Below is the relevant code in the form, show, and index views in Active Admin.

    ActiveAdmin.register Post do
    index do
        column "Post Title", :title
        column :blog
        column :published_on
        column :status
        column "Category", :categories do |post|
            post.categories.collect { |cat|  cat.name }.join(", ")
        end
        default_actions
    end 
    
    show do
        h5 "Created by #{post.blog.name} on #{post.created_at.strftime('%B %-d, %Y')}"
        h5 "Categories: #{post.categories.collect { |cat|  cat.name }.join(", ")}"
        h5 "Current Status: #{post.status}"
        h5 "Published On Date: #{post.published_on.strftime('%B %-d, %Y')} - (will only be posted if marked with Publish as status)"
        div do
            simple_format post.body
        end
    end
    
    form do |f|
        f.inputs "Details" do
            f.input :blog, hint: "Select a blog"
            f.input :title, hint: "Enter blog post title"
            f.input :published_on, as: :date, include_blank: false, hint: "Select a date", :prompt => {:day => "Day", :month => "Month", :year => "Year"}, :start_year => Time.now.year
            f.input :status, as: :select, collection: ["Draft", "Published"], include_blank: false, hint: 'Select "Draft" to save and post later, and "Publish" to post now'
            f.input :categories, as: :check_boxes, collection: Category.all
            f.input :body, input_html: { class: "redactor", id: "redactor" }
        end
        f.buttons
    end  
    end