Fix Rails Form

The task at hand: Instructions

  • To make a form look better. This is how it looks right now.
  • Please keep all the admin items together.
  • You do not need to change the stylesheet, simply use bootstrap and your creativity to present the form better to the end user.

Here is the form as it now stands. The layout needs improvement:

_config.yml

General Notes:

  • Please infer the things that you need to do from the limited information you have below. I have provided some notes to help guide you:

Bootstrap

We are using bootstrap. Add this to your Gemfile: gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git'

Models.

Give then form I am giving you, please infer the other models and relations that are required to make it work.

  • We have a quote.rb model, and a line_item model. A quote has many line_items.
  • We also have a user model. You needn’t worry about (devise)[https://github.com/plataformatec/devise] but you can if you want to. The main thing is that a user model must have a corresponding table with an email column and an ID column, and also an admin attribute. You could add the admin columns as a simple boolean on the users table.
  • The LineItemType model has only one column: “Name”

The Main Schema

Here is the schema for the Line Items:

  create_table "line_items", force: :cascade do |t|
    t.integer "quote_id"
    t.decimal "price", default: "0.0", null: false
    t.decimal "po_value"
    t.string "po_number"
    t.text "scope_description"
    t.date "delivery_date"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "delivery_time", limit: 400
    t.decimal "hours", default: "0.0"
    t.text "justification"
    t.text "links"
    t.integer "user_id"
    t.text "approval_link"
    t.boolean "was_sent", default: false
    t.bigint "line_item_type_id"
    t.string "invoice_state"
    t.string "invoice_no"
    t.string "issue_state"
    t.integer "item_index"
    t.index ["line_item_type_id"], name: "index_line_items_on_line_item_type_id"
    t.index ["quote_id"], name: "index_line_items_on_quote_id"
  end
  

The Form:

  • I am using active storage on each line item. That why you can attach files to every line item.
<%= form_with(model: @line_item.new_record? ? [@quote, @line_item] : @line_item ) do |f| %>
  <%= render 'shared/errors', object: @line_item %>
  <%= f.label(:scope_description) %>
  <%= f.text_area(:scope_description, class: "form-control") %> <br>
  <div class="row">
    <%= f.label(:hours, class: "col-sm-2 col-form-label") %>
    <%= f.number_field(:hours, class: "col-sm-2") %>
    <%= f.label(:delivery_time, class: "col-sm-2 col-form-label") %>
    <%= f.text_field(:delivery_time, class: "col-sm-2") %>
  </div>
  <br>
  <% if current_user.admin?%>
    <h4> Admin Panel Items</h4>
    <div class="form-group row">
      <% if @line_item.user.role == 'basic' %>
        <p> (You cannot overwrite the price that a basic_user has created. The price is calculated from the hours inputted) </p>
      <% end %>
      <%= f.label(:price, class: "col-sm-2 col-form-label") %>
      <%= f.text_field(:price, class: "col-sm-2") %>
      <%= f.label(:po_value,  class: "col-sm-2 col-form-label") %>
      <%= f.text_field(:po_value, class: "col-sm-2") %>
      <%= f.label(:invoice_no,  class: "col-sm-2 col-form-label") %>
      <%= f.text_field(:invoice_no, class: "col-sm-2") %>
      <%= f.label(:po_number,  class: "col-sm-2 col-form-label") %>
      <%= f.text_field(:po_number, class: "col-sm-2") %>    <br>
      <%= f.label(:justification) %>
      <%= f.text_area(:justification, class: "form-control") %> <br>
    </div>
    <div class="actions form-group">
      <p> <b> Do Not Use: Except in case an error was made: </b> </p>
      <%= f.label(:invoice_state) %>
      <%= f.select(:invoice_state, @line_item.invoice_states_for_select, {:selected => @line_item.invoice_state } ) %>
    </div>
    <div class="actions form-group">
      <p> <b> Do Not Use: Except in case an error was made: </b> </p>
      <%= f.label(:issue_state) %>
      <%= f.select(:issue_state, @line_item.issue_states_for_select, {:selected => @line_item.issue_state } ) %>
    </div>
    <div class="form-group row">
      <%= f.label(:approval_link) %>
      <%= f.text_area(:approval_link, class: "form-control") %>
    </div>
    <div class="gorm-group row">
      <%= f.select(:line_item_type_id, LineItemType.all.collect { |u| [u.name, u.id]}, {:include_blank => false, prompt: 'Please Choose Line Item Type', selected: @line_item.line_item_type_id }, class: "form-control", label:'users', :multiple => false   )%>
    </div>
  <% else %>
    <%= f.hidden_field :line_item_type_id, :value => @line_item.line_item_type.id %>
  <% end %>
  <%= f.label(:links) %>
  <%= f.text_field(:links, class: "form-control") %> <br>
  <% if current_user.role == "admin" %>
    <%= f.label(:user) %> <br>
    <%= f.select(:user_id, User.all.collect { |u| [u.email, u.id]}, {:include_blank => false, prompt: 'Please select detailer', selected: @line_item.user_id }, class: "form-control", label:'users', :multiple => false   )%>
  <% else %>
    <% if @line_item.new_record? %>
      <%= f.hidden_field :user_id, :value => current_user.id %>
    <% end %>
  <% end %>
  <br>
  <p> You can select multiple files in a single upload:</p>
  <%= f.file_field :files, multiple: true%>
  <%= f.file_field :files, multiple: true %>
  <br>
  <br>
  <div class="form-buttons">
    <%= f.submit "Submit", class: "btn btn-primary btn-block" %> <br>
  </div>
<% end %>

And here is the application.html.erb if you wanted to have a look:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= content_for?(:title) ? yield(:title) : "Quotes" %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag "application", :media => "all" %>
    <%= javascript_include_tag "application" %>
    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
    <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript"></script>
    <![endif]-->
  </head>
  <body>
    <%= render 'layouts/nav-bar' %>
    <div class="container">
      <%= bootstrap_flash %>
      <%= yield %>
      <!--/span-->
      <footer>
        <p>&copy; Tek1 - <%= mail_to 'ben.chenathara@gmail.com', 'Ben Koshy' %> - Please email for Required Changes/Suggestions - Quotation App 2018 </p>
      </footer>
    </div>
    <!-- /container -->
  </body>
</html>

Written on October 14, 2019