I'm busy with a invoicing application and i'm trying to put a nested form from the cocoon gem inside a <tbody></tbody>. The nested form is working perfectly but it doesn't show up in the <tbody></tbody> but at some random place above the table head. I think it's because you can't have <div class=nested-fields></div> inside the table body but i'm not sure how to do it differently.
i have this in my invoices/_form.html.erb :
<%= form_for #invoice do |f| %>
<% if #invoice.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#invoice.errors.count, "error") %> prohibited this invoice from being saved:</h2>
<ul>
<% #invoice.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="row">
<div class="col-sm-12">
<table class="table table-striped">
<thead>
<tr>
<th class="hidden-480"> Hoeveelheid </th>
<th class="hidden-480"> Beschrijving </th>
<th class="hidden-480"> Bedrag </th>
<th class="hidden-480"> Totaal </th>
<th class="hidden-480"> Btw(%) </th>
</tr>
</thead>
<tbody>
<%= f.fields_for :products do |product| %>
<%= render 'product_fields', f: product %>
<%= link_to_add_association 'Item toevoegen', f, :products, class: 'btn btn-primary btn-success' %>
<% end %>
</tbody>
</table>
</div>
</div>
<% end %>
invoices/_product_fields.html.erb
<div class="nested-fields">
<tr>
<td> <%= f.text_field :quantity %> </td>
<td> <%= f.text_area :description %> </td>
<td> <%= f.number_field :unitprice %> </td>
<td> €200 </td>
<td> <%= f.select(:btw, [[' 21%', 21, title: '21%'],[' 6%', 6, title: '6%'], [' 0%', 0, title: '0%']]) %> </td>
</tr>
<%= link_to_remove_association 'x', f, class: 'btn btn-primary btn-danger' %>
</div>
Invoice.rb - model
class Invoice < ActiveRecord::Base
has_one :company
has_one :customer
has_many :products
accepts_nested_attributes_for :customer, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :products, reject_if: :all_blank, allow_destroy: true
validates :number, :currency, :date, :duedate, :btwtotal, :subtotal, :total, presence: true
end
Product.rb - model
class Product < ActiveRecord::Base
belongs_to :invoice
end
Invoices_controller.rb
class InvoicesController < ApplicationController
before_action :set_invoice, only: [:show, :edit, :update, :destroy]
# GET /invoices
# GET /invoices.json
def index
#invoices = Invoice.all
end
# GET /invoices/1
# GET /invoices/1.json
def show
end
# GET /invoices/new
def new
#invoice = Invoice.new
#invoice.products.build
end
# GET /invoices/1/edit
def edit
end
# POST /invoices
# POST /invoices.json
def create
#invoice = Invoice.new(invoice_params)
respond_to do |format|
if #invoice.save
format.html { redirect_to #invoice, notice: 'Invoice was successfully created.' }
format.json { render :show, status: :created, location: #invoice }
else
format.html { render :new }
format.json { render json: #invoice.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /invoices/1
# PATCH/PUT /invoices/1.json
def update
respond_to do |format|
if #invoice.update(invoice_params)
format.html { redirect_to #invoice, notice: 'Invoice was successfully updated.' }
format.json { render :show, status: :ok, location: #invoice }
else
format.html { render :edit }
format.json { render json: #invoice.errors, status: :unprocessable_entity }
end
end
end
# DELETE /invoices/1
# DELETE /invoices/1.json
def destroy
#invoice.destroy
respond_to do |format|
format.html { redirect_to invoices_url, notice: 'Invoice was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_invoice
#invoice = Invoice.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def invoice_params
params.require(:invoice).permit(:number, :currency, :date, :duedate, :btwtotal,
:subtotal, :total, :footer, customers_attributes: [:id, :company_name, :address_line_1, :zip_code, :_destroy],
companies_attributes: [:id, :btw_number, :iban_number, :kvk_number, :company_name, :_destroy],
products_attributes: [:id, :quantity, :description, :unitprice, :btw, :total])
end
end
Any idea what's going on? Help would be much appreciated!
You can simply use built in methods provided by cocoon gem for link_to_add_association,
reference:
https://github.com/nathanvda/cocoon#link_to_add_association
<%= link_to_add_association 'Item toevoegen', f, :products,:"data-association-insertion-node" => "tbody#{id of tbody encapsulating your fields_for}",:"data-association-insertion-method" => "append", class: 'btn btn-primary btn-success' %>
P.S this is my first answer in stackoverflow, so I apologize in advance if I wasn't clear enough.
You can refer to Control the Insertion Behaviour section of cocoon gem for more reference to insert nested fields.
For example,
$(document).ready(function() {
$("#owner a.add_fields").
data("association-insertion-method", 'append').
data("association-insertion-traversal", 'closest').
data("association-insertion-node", '#parent_table');
});
Related
I'm trying to create an app, where a practitioner can add opening days and hours. The problem right now is, that when I hit the save button, it only creates one record. It should be creating a record for every day of the week.
So it would be
monday: open 9.00 - close 17.00
tuesday: open 8.30 - close 16.30
etc.
_form.html.erb
<script type="text/javascript">
$(document).ready(function () {
$('input:checkbox').bootstrapSwitch();
});
</script>
<%= #schedule.errors.full_messages %>
<%= simple_form_for([:clinic, :practitioner, #schedule]) do |f| %>
<table id="modal">
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<% Schedule.days.each do |day| %>
<tbody>
<tr>
<td id="modal-column-left" style="background-color:#aaa;">
<p>Åbningstider</p>
</td>
<td id="modal-column-right" style="background-color:#bbb;">
<p>Åbent/lukket</p>
</td>
</tr>
<tr>
<td id="modal-column-left" style="background-color:#aaa;">
<h2 style="margin-bottom: 5%;">
<h2 style="margin-bottom: 5%;"><%= day.titleize %>: <%= Date.today.send(day) %></h2>
<%= f.check_box :open_or_not, :data => { :size=>'small', 'on-color'=>'success', 'on-text'=>'YES', 'off-text'=>'NO' } %>
</td>
<td id="modal-column-right" style="background-color:#bbb;"><%= f.input :open_time %> <%= f.input :close_time %>
</td>
</tr>
</tbody>
<% end %>
</table>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
schedules_controller.rb
class SchedulesController < ApplicationController
before_action :set_schedule, only: [:show, :edit, :update, :destroy]
# GET /schedules
# GET /schedules.json
def index
#schedules = Schedule.all
end
# GET /schedules/1
# GET /schedules/1.json
def show
end
# GET /schedules/new
def new
#schedule = Schedule.new
#schedules = Schedule.all
end
# GET /schedules/1/edit
def edit
end
# POST /schedules
# POST /schedules.json
def create
#schedule = Schedule.new(schedule_params)
respond_to do |format|
if #schedule.save
format.html { redirect_to clinic_practitioner_schedule_path(id: #schedule.id), notice: 'Schedule was successfully created.' }
format.json { render :show, status: :created, location: #schedule }
else
format.html { render :new }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /schedules/1
# PATCH/PUT /schedules/1.json
def update
respond_to do |format|
if #schedule.update(schedule_params)
format.html { redirect_to clinic_practitioner_schedule_path(#schedule), notice: 'Schedule was successfully updated.' }
format.json { render :show, status: :ok, location: #schedule }
else
format.html { render :edit }
format.json { render json: #schedule.errors, status: :unprocessable_entity }
end
end
end
# DELETE /schedules/1
# DELETE /schedules/1.json
def destroy
#schedule.destroy
respond_to do |format|
format.html { redirect_to clinic_practitioner_schedules_url, notice: 'Schedule was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_schedule
#schedule = Schedule.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def schedule_params
params.require(:schedule).permit(:title, :start, :end, :practitioner_id, :account_id, :open_or_not, :day_of_week, :open_time, :close_time)
end
end
Read the documentation of complex forms.
You will want to attach multiple schedules to the Practitioner:
class Practitioner < ApplicationRecord
has_many :schedules
accepts_nested_attributes_for :schedules
end
The Controller
def practitioner_params
params.require(:practitioner).permit(:name, schedule_attributes: [:id, :open_or_not, :day_of_week, :open_time, :close_time])
end
And in the form:
<%= simple_form_for #practitioner do |f| %>
<%= f.input :name %>
<%= f.simple_fields_for :schedules do |s| %>
<%= s.input :open_or_not %>
<%= s.input :day_of_week %>
<%= s.input :open_time %>
<%= s.input :close_time %>
<% end %>
<% end %>
To dynamically add rows use the Cocoon gem.
I have a landlord and landlord_address model. When a new landlord_address is created, the landlord_id is saved to the table. For some reason, when I edit a landlord_address the landlord_id is changed to NULL.
Models:
class Landlord < ActiveRecord::Base
has_many :landlord_addresses, dependent: :destroy
belongs_to :listing_agent, class_name: 'Agent'
end
class LandlordAddress < ActiveRecord::Base
belongs_to :landlord
has_many :landlord_companies, dependent: :destroy
end
Landlord Addresses Controller:
module Matrix
class LandlordAddressesController < ApplicationController
before_action :set_landlord_address, only: [:show, :edit, :update, :destroy]
# GET /landlord_addresses
# GET /landlord_addresses.json
def index
#landlord = Landlord.find(params[:landlord_id])
#landlord_addresses = #landlord.landlord_addresses.order(address_line_one: :asc)
end
# GET /landlord_addresses/1
# GET /landlord_addresses/1.json
def show
end
# GET /landlord_addresses/new
def new
#landlord_address = LandlordAddress.new
#landlord = Landlord.find(params[:landlord_id])
end
# GET /landlord_addresses/1/edit
def edit
end
# POST /landlord_addresses
# POST /landlord_addresses.json
def create
#landlord_address = LandlordAddress.new(landlord_address_params)
respond_to do |format|
if #landlord_address.save
format.html { redirect_to matrix_landlord_landlord_addresses_path, notice: 'Landlord address was successfully created.' }
format.json { render :show, status: :created, location: #landlord_address }
else
format.html { render :new }
format.json { render json: #landlord_address.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /landlord_addresses/1
# PATCH/PUT /landlord_addresses/1.json
def update
respond_to do |format|
if #landlord_address.update(landlord_address_params)
format.html { redirect_to matrix_landlord_landlord_addresses_path, notice: 'Landlord address was successfully updated.' }
format.json { render :show, status: :ok, location: #landlord_address }
else
format.html { render :edit }
format.json { render json: #landlord_address.errors, status: :unprocessable_entity }
end
end
end
# DELETE /landlord_addresses/1
# DELETE /landlord_addresses/1.json
def destroy
#landlord_address.destroy
respond_to do |format|
format.html { redirect_to landlord_addresses_url, notice: 'Landlord address was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_landlord_address
#landlord_address = LandlordAddress.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def landlord_address_params
params.require(:landlord_address).permit(:address_line_one, :address_line_two, :city, :state, :zip, :super_name, :super_number, :landlord_id, :latitude, :longitude)
end
end
end
Landlord Addresses _form:
<div class="feedback-container">
<%= form_for [:matrix, #landlord_address] do |f| %>
<% if #landlord_address.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#landlord_address.errors.count, "error") %> prohibited this landlord_address from being saved:</h2>
<ul>
<% #landlord_address.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
/ul>
</div>
<% end %>
<div id="form-map"></div>
<input id="pac-input" class="controls" type="text"
placeholder="Enter a location">
<div id="type-selector" class="controls">
<input type="radio" name="type" id="changetype-all" checked="checked">
<label for="changetype-all">All</label>
</div>
<div class="field">
<%= f.label :address, class: "general-text-label" %>
<%= f.text_field :address_line_one, class: "general-text-field map-autocomplete-address" %>
<%= f.hidden_field :latitude, class: "map-autocomplete-latitude" %>
<%= f.hidden_field :longitude, class: "map-autocomplete-longitude" %>
</div>
<div class="field">
<%= f.label :super_name, class: "general-text-label" %><br>
<%= f.text_field :super_name, class: "general-text-field" %>
</div>
<div class="field">
<%= f.label :super_number, class: "general-text-label" %><br>
<%= f.text_field :super_number, class: "general-text-field" %>
</div>
<div class="field">
<%= f.hidden_field :landlord_id, :value => params[:landlord_id] %>
</div><br>
<div class="actions">
<%= f.submit "Submit", class: "btn btn-black btn-4x" %>
</div>
<% end %>
</div>
Routes:
namespace :matrix do
resources :landlords, shallow: true do
resources :landlord_addresses do
resources :landlord_companies
end
end
end
New Error:
This part
<%= f.hidden_field :landlord_id, :value => params[:landlord_id] %>
will be your issue. When params[:landlord_id] is nil your record will be updated to null.
You should change it to
<%= f.hidden_field :landlord_id, :value => #landlord_address.landlord_id || #landlord.id %>
or some thing else.
Your route is nested, You dnt need to assign in hidden field. You can do it in the controller, passing params.
Form:
Remove hidden field, we are assigning it in the controller!
<div class="field">
<%= f.hidden_field :landlord_id, :value => params[:landlord_id] %>
</div><br>
Controller:
# POST /landlord_addresses
# POST /landlord_addresses.json
def create
#landlord_address = LandlordAddress.new(landlord_address_params)
# add this line here!
#landlord_address.landlord_id = params[:landlord_id]
respond_to do |format|
if #landlord_address.save
format.html { redirect_to matrix_landlord_landlord_addresses_path, notice: 'Landlord address was successfully created.' }
format.json { render :show, status: :created, location: #landlord_address }
else
format.html { render :new }
format.json { render json: #landlord_address.errors, status: :unprocessable_entity }
end
end
end
private
#ALSO REMOVE `:landlord_id` from
def landlord_address_params
params.require(:landlord_address).permit(:address_line_one, :address_line_two, :city, :state, :zip, :super_name, :super_number, :latitude, :longitude)
end
I have a weird problem with "nested_form" in Rails. I made a model "evaluate" associated to other model "proyect", but when I try to show theres fields, on "proyects" form, just show fields from "proyects".
Here is my code:
Models:
proyect.erb
class Proyect < ActiveRecord::Base
belongs_to :user
has_many :vercions #I know is versions
has_many :evaluates #I know is evaluators
accepts_nested_attributes_for :evaluates, allow_destroy: true
validates :titulo,:presence => true,
:length => { :minimum => 3 }
validates :descripcion,:presence => true,
:length => { :minimum => 3 }
end
evaluate.erb
class Evaluate < ActiveRecord::Base
belongs_to :proyect
has_and_belongs_to_many :users
end
Controller
proyects_controller.erb
class ProyectsController < ApplicationController
before_action :set_proyect, only: [:show, :edit, :update, :destroy]
# GET /proyects
# GET /proyects.json
def index
if current_user.tipo == 'i'
#proyects = Proyect.where(:user_id => current_user.id)
else
#proyects = #Proyect.where(:id_user => current_user.id)
Proyect.all
end
end
# GET /proyects/1
# GET /proyects/1.json
def show
#vercion = Vercion.new
end
# GET /proyects/new
def new
#proyect = Proyect.new
#proyect.evaluates.build
end
# GET /proyects/1/edit
def edit
end
# POST /proyects
# POST /proyects.json
def create
#proyect = current_user.proyects.new(proyect_params)
respond_to do |format|
if #proyect.save
format.html { redirect_to #proyect, notice: 'Proyecto creado!.' }
format.json { render :show, status: :created, location: #proyect }
else
format.html { render :new }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
# Llamamos al ActionMailer que creamos
Usermailer.bienvenido_email(current_user,#proyect).deliver
end
end
# PATCH/PUT /proyects/1
# PATCH/PUT /proyects/1.json
def update
respond_to do |format|
if #proyect.update(proyect_params)
format.html { redirect_to #proyect, notice: 'Proyect was successfully updated.' }
format.json { render :show, status: :ok, location: #proyect }
else
format.html { render :edit }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
end
end
# DELETE /proyects/1
# DELETE /proyects/1.json
def destroy
#proyect.destroy
respond_to do |format|
format.html { redirect_to proyects_url, notice: 'Proyect was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_proyect
#proyect = Proyect.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def proyect_params
params.require(:proyect).permit(
:titulo, :descripcion,:evaluador, :id_user, :codigo, :user_assign,evaluates_attributes: [:id,:nombre, :prioridad, :_destroy, user_ids: [] ])
end
end
Views
_form.html.erb (Proyects)
<%= nested_form_for(#proyect) do |f| %>
<% if #proyect.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#proyect.errors.count, "error") %> prohibited this proyect from being saved:</h2>
<ul>
<% #proyect.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :titulo %><br>
<%= f.text_field :titulo %>
</div>
<div class="field">
<%= f.label :descripcion %><br>
<%= f.text_area :descripcion %>
</div>
<div class="field">
<%= f.hidden_field :id_user, :value => current_user.id %>
</div>
<!--Aqui añadi algo-->
<fieldset id="evaluates">
<%= f.fields_for :evaluates do |evaluates_form| %>
<div class="field">
<%= evaluates_form.label :status %><br>
<%= evaluates_form.text_field :status %>
</div>
<%= evaluates_form.link_to_remove "Eliminar esta tarea" %>
<% end %>
<p><%= f.link_to_add "Agregar una tarea", :evaluates %></p>
</fieldset>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
_evaluate_fields.html.erb
<div class="field">
<%= f.label :status, 'Nombre de la tarea' %><br>
<%= f.text_field :status %>
</div>
<div class="field">
<%= f.collection_check_boxes :user_ids, User.where(:tipo => 'e'), :id, :cedula %>
</div>
<%= f.link_to_remove "Eliminar Evaluador" %>
I am having issues understanding this.
What am I trying to accomplish?
Selected items in dropdown submitted to inventory.
Change the status of each item in a form in its own model.
Problem
I submit a form and the status of each item in the dropdown doesn't get submitted.
Any help would be appreciated.
Thanks in advance!
Form Code
<%= form_for(#inventory, html: {class: "form-horizontal"}) do |f| %>
<% if #inventory.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#inventory.errors.count, "error") %> prohibited this inventory from being saved:</h2>
<ul>
<% #inventory.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :tablet_id, "Tablet #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "tablet_id", Tablet.where("status = '1'").all.collect{ |t| [t.alias, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :tablet do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<%= f.label :chauffeur_id, "Chauffeur #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "chauffeur_id", Chauffeur.where("status = '1'").all.collect{ |t| [t.chaufNum, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :chauffeur do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<%= f.label :vehicle_id, "Vehicle #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "vehicle_id", Vehicle.where("status = '1'").all.collect{ |t| [t.vehNum, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :vehicle do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<div class="col-md-2 col-md-offset-2">
<%= f.submit class: "btn btn-sm btn-success" %>
</div>
</div>
<% end %>
Model (Inventory)
class Inventory < ActiveRecord::Base
belongs_to :tablet
belongs_to :chauffeur
belongs_to :vehicle
accepts_nested_attributes_for :tablet
accepts_nested_attributes_for :chauffeur
accepts_nested_attributes_for :vehicle
has_paper_trail
validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }
end
Inventory Controller
class InventoriesController < ApplicationController
before_action :authenticate_user!
before_filter :set_paper_trail_whodunnit
before_action :set_inventory, only: [:show, :edit, :update, :destroy]
# GET /inventories
# GET /inventories.json
def index
#inventories = Inventory.all.paginate(:page => params[:page], :per_page => 15)
end
# GET /inventories/1
# GET /inventories/1.json
def show
#versions = PaperTrail::Version.order('created_at DESC')
end
# GET /inventories/new
def new
#inventory = Inventory.new
end
# GET /inventories/1/edit
def edit
end
def history
#versions = PaperTrail::Version.order('created_at DESC')
end
# POST /inventories
# POST /inventories.json
def create
# #inventory = Inventory.new(inventory_params)
render plain: params[:inventory].inspect
# respond_to do |format|
# if #inventory.save
# format.html { redirect_to #inventory, notice: 'Inventory was successfully created.' }
# format.json { render :show, status: :created, location: #inventory }
# else
# format.html { render :new }
# format.json { render json: #inventory.errors, status: :unprocessable_entity }
# end
# end
end
# PATCH/PUT /inventories/1
# PATCH/PUT /inventories/1.json
def update
respond_to do |format|
if #inventory.update(inventory_params)
format.html { redirect_to #inventory, notice: 'Inventory was successfully updated.' }
format.json { render :show, status: :ok, location: #inventory }
else
format.html { render :edit }
format.json { render json: #inventory.errors, status: :unprocessable_entity }
end
end
end
# DELETE /inventories/1
# DELETE /inventories/1.json
def destroy
#inventory.destroy
respond_to do |format|
format.html { redirect_to inventories_url, notice: 'Inventory was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_inventory
#inventory = Inventory.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def inventory_params
params.require(:inventory).permit(:tablet_id, :chauffeur_id, :vehicle_id, tablet_attributes: [:status => '2'], chauffeur_attributes: [:status => '2'], vehicle_attributes: [:status => '2'])
end
end
Clean all your nested attribute code. This is not what you want. So model like this:
class Inventory < ActiveRecord::Base
belongs_to :tablet
belongs_to :chauffeur
belongs_to :vehicle
has_paper_trail
validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }
end
Now, what you want to use a rails callback so that when you create an inventory then you update the status of other things. This goes on your model too:
class Inventory < ActiveRecord::Base
...
after_create :update_status
protected
def update_status
self.tablet.update_attribute(:status, 2)
self.chauffeur.update_attribute(:status, 2)
self.vehicle.update_attribute(:status, 2)
end
end
Also remember to clean all your fields_for code and your strong parameters on your controller...you don't need the nested ones anymore.
grading.rb
class Grading
require 'autoinc'
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Autoinc
field :quantity, type: Float
field :count, :type => Float
field :grade_id, type: Integer
field :batch_id, type: Integer
field :variety_id, type: Integer
field :serial_id, :type => Integer
field :soaked, :type => Boolean
# Mongoid AutoInc
increments :serial_id
# Associations
belongs_to :grade
belongs_to :variety
belongs_to :batch
has_many :grading_weighments, :dependent=> :destroy
# validations
validates_presence_of :grade_id,:batch_id,:variety_id
validates_presence_of :quantity , numericality: {:greater_than => 0}
validates_presence_of :count ,numericality: {:greater_than_or_equal_to => 10, :less_than_or_equal_to => 150}
attr_accessor :weights
accepts_nested_attributes_for :grading_weighments, :allow_destroy => true
end
gradingcontroller.rb
class GradingsController < ApplicationController
before_action :set_grading, only: [:show, :edit, :update, :destroy]
# load_and_authorize_resource
# GET /gradings
# GET /gradings.json
def index
#gradings = Grading.all.order('date DESC')
#q = Batch.search(params[:q])
#batches = #q.result(:distinct => true).in(status:["HLQDone","GradingDone"]).order('updated_at ASC').page(params[:page]).per(5)
# #batches = Batch.all.order('created_at DESC').page(params[:page]).per(5) .where(status: "HLQ_Done")
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
respond_to do |format|
format.js
format.html
end
end
# GET /gradings/1
# GET /gradings/1.json
def show
end
# GET /gradings/new
def new
#grading = Grading.new
end
# GET /gradings/1/edit
def edit
end
# POST /gradings
# POST /gradings.json
def create
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
#grading = Grading.new(grading_params)
#batch= #grading.batch
weights=params[:grading][:weights]
#grading.quantity= weights.map! { |i| i.to_f }.sum
respond_to do |format|
if #grading.save
#grading_weighments=GradingWeighment.new
#grading_weighments.grading_id =#grading.id
#grading_weighments.weights =weights.join(',')
#grading_weighments.save
format.html { redirect_to gradings_path, notice: 'Grading was successfully created.' }
format.json { render action: 'show', status: :created, location: #grading }
format.js
else
format.html { render action: 'new' }
format.json { render json: #grading.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gradings/1
# PATCH/PUT /gradings/1.json
def update
g=[]
puts "#{params[:grading][:grading_weighments_attributes]}"
params[:grading][:grading_weighments_attributes].each do |key,value|
g<<value[:weights]
end
puts "=============#{g}"
q= g.map{ |i| i.to_f }.sum
puts "==========aes==#{q}"
#grading.update_attributes(quantity: q)
#gw= GradingWeighment.find_or_create_by(grading_id: #grading.id)
#gw.update_attributes(weights: g.join(','))
respond_to do |format|
if #grading.update(grading_params)
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
format.html { redirect_to gradings_path, notice: 'Grading was successfully updated.' }
format.json { respond_with_bip(#grading) }
format.js
else
format.html { render action: 'edit' }
format.json { render json: #grading.errors, status: :unprocessable_entity }
format.js
end
end
end
# DELETE /gradings/1
# DELETE /gradings/1.json
def destroy
#grading_id=#grading.id
batch_number= #grading.batch.batch_number
#grading.destroy
respond_to do |format|
#del_batch = Batch.find_by(batch_number: batch_number)
#length=#del_batch.gradings.length
#del_batch.update_attributes(status: "HLQ_Done") if #length==0
format.html { redirect_to gradings_url }
format.json { head :no_content }
format.js
end
end
def fetch_weights
#grading_weighments=GradingWeighment.find_by(grading_id: params[:id]).weights
#grading=Grading.find(params[:id])
(#grading.grading_weighments.first.weights.split(',').length-1).times {#grading.grading_weighments.build}
respond_to do |format|
format.html { render :nothing => true, :status => 200, :content_type => 'text/html'}
format.json { head :no_content }
format.js
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_grading
#grading = Grading.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def grading_params
params.require(:grading).permit(:quantity,:batch_id,:variety_id,:grade_id,:count, :weights,:grading_weighments_attributes, :soaked)
end
end
list.html.erb
<thead>
<tr>
<th>Count</th>
<th>Grade</th>
<th>Variety</th>
<th>Quantity</th>
<th>Soaked</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<%batch= #batch if !batch%>
<%if batch.gradings.length==0%>
<tr><td colspan="5" class="warning">Grading is not done for batch with number <%=batch.batch_number%></td></tr>
<%else%>
<%gradings=batch.gradings.order('created_at DESC')%>
<%gradings.each do |grading|%>
<tr id="<%=grading.id%>">
<td><%= best_in_place grading, :count, :as => :input, required:true%></td>
<td><%= best_in_place grading, :grade_id, :as => :select, :collection => #grades %></td>
<td><%= best_in_place grading, :variety_id, :as => :select, :collection => #varieties %></td>
<td><%= best_in_place grading, :quantity, :as => :input%></td>
<td><%= best_in_place grading, :soaked, :as => :input, required:true%></td>
<td>
<%= link_to "getweights/#{grading.id}", method: :get, :remote => true ,class:'btn btn-info' do%>
<i class="fa fa-plus"></i>
<% end %>
<%= link_to grading, method: :delete, remote:true,data: { confirm: 'Are you sure?' } ,title:'Delete this grading', class:'btn btn-danger' do%>
<i class="fa fa-trash-o"></i>
<%end%>
</td>
</tr>
<%end%>
<%end%>
</tbody>
</table>
new.grading.html.erb
<div class="form-group">
<%= f.label :soaked ,class:"sr-only"%>
<%= f.select :soaked ,options_for_select(["Soaked", "Un-soaked"]), {:include_blank => "Select Soaking"}, class: "form-control" , autocomplete:"off", required: true %>
</div>
Here i am added new field called as "field :soaked, :type => Boolean", this field is not saved in database and not showing in views. How can solve this problem please help me.
Note: I passed grading params (soaked) also.
Try this:
<%= f.select :active, [['Soaked', true], ['Un-soaked', false]] %>
soaked will only accept TRUE or FALSE, while you are trying to save "Soaked", "Un-soaked"
<%= f.check_box :soaked %>
You can use CHECKBOX.
If you still want to use "Soaked" and "Un-soaked". You can apply check in your controller. If Soaked is selected then save TRUE else FALSE
Try This One
<%= f.select :soaked, options_for_select([['Soaked', true], ['Un-soaked', false]]) %>