Sort the balance column in ruby on rails 6 - ruby

I am trying to calculate and sort the balance column in the table as per the image shown below;
For that, I used #mexpenses = #mexpenses.sort { |e| e.balance } for sorting as it results in undesired results so I commented out in the code below.
I would like to achieve the results as shown in the rightmost BALANCE column in the above image.
Everything in the table from the Date column to the Debit column is shown as desired only the Balance column is causing the issue.
I would like to get the latest record at the top of the statement with the appropriate balance.
Note: No balance column is in the database.
mexpenses_controller.rb
def index
#mexpenses = Mexpense.order('date DESC')
balance = 763.87
#mexpenses.each do |e|
balance += e.credit.to_f - e.debit.to_f
e.balance = balance
end
# #mexpenses = #mexpenses.sort { |e| e.balance }
respond_to do |format|
format.html
format.xls
end
end
Mexpense.rb
class Mexpense < ActiveRecord::Base
validates :particulars, presence: true
validates :date, presence: true
attr_accessor :balance
after_initialize :init
def init
self.balance = 0
end
end
index.html.erb
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="table-responsive myTable">
<table class="table listing text-center">
<tr class="tr-head">
<td>Date</td>
<td>Particulars</td>
<td>Credit</td>
<td>Debit</td>
<td>Balance</td>
</tr>
<tr>
<td></td>
</tr>
<% #mexpenses.each do |mexpense| %>
<tr class="tr-<%= cycle('odd', 'even') %>">
<td class="col-1"><%= mexpense.date.strftime('%d/%m/%Y') %></td>
<td class="col-1" style="width: 50%;"><%= link_to mexpense, mexpense %></td>
<td class="col-1 neg" style="width: 10%;"><%= number_with_precision(mexpense.credit, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 pos" style="width: 10%;"><%= number_with_precision(mexpense.debit, :delimiter => ",", :precision => 2) %></td>
<td><%= number_with_precision(mexpense.balance, :delimiter => ",", :precision => 2) %></td>
</tr>
<% end %>
</table>
</div>
</div>
</div>
20210213052730_create_mexpenses.rb
class CreateMexpenses < ActiveRecord::Migration
def change
create_table :mexpenses do |t|
t.date :date
t.string :particulars
t.decimal :debit
t.decimal :credit
t.timestamps null: false
end
end
end
Any suggestions are most welcome.
Thank you in advance.

I strongly recommend to store the balance column in the database. Each time debit or credit is changed, the balance column will be updated.
store MONEY as integer!!!! This avoids floating point rounding errors.
console:
rails g migration add_balance_to_mexpenses balance:integer
migration:
add_column :mexpenses, :balance, :integer, default: 0, null: false
mexpence.rb - update balance column whenever a `mexpence is changed
after_save do
update :balance, credit - debit
end
Now you can easily order by balance that is a separate field in your database. Something like:
#mexpenses = Mexpense.order(date: :desc, balance: :desc)

Related

Grouping records by user in Admin view

I would like to get all records with their usernames when signed in as Admin. For that my controller code is as below;
amol361s_controller.rb
def index
if current_user.admin
#amol361s = Amol361.all.search(params[:search]).order("created_at ASC")
#users = User.all.amol361s
else
#amol361s = current_user.amol361s.all.search(params[:search]).visible.order("created_at ASC")
end
respond_to do |format|
format.html
format.js
end
end
index.html.erb
<tbody id = "kola">
<% #users.each do |user| %>
<%= user.amol361s.each do |amol361| %>
<tr class="tr-<%= cycle('odd', 'even') %>" id='<%= "tr_#{amol361.id}" %>'>
<% if current_user && current_user.admin %>
<td class="col-1"><%= link_to amol361.date.try(:strftime,'%d/%m/%Y'), edit_amol361_path(amol361) %></td>
<% else %>
<td class="col-1"><%= amol361.date.try(:strftime,'%d/%m/%Y') %></td>
<% end %>
<td class="col-3"><%= span_with_possibly_red_color amol361.description %></td>
<td class="col-1"><%= number_with_precision(amol361.amount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(amol361.discount, :delimiter => ",", :precision => 2) %></td>
<td class="col-1 neg"><%= number_with_precision(amol361.paid, :delimiter => ",", :precision => 2) %></td>
<% #balance += amol361.amount.to_f - amol361.discount.to_f - amol361.paid.to_f %>
<% color = #balance >= 0 ? "pos" : "neg" %>
<td class="col-1 <%= color %>"><%= number_with_precision(#balance.abs, :delimiter => ",", :precision => 0) %></td>
<td class="col-1"><%= amol361.delndel %></td>
<td class="col-1"><%= amol361.remark %></td>
<% if current_user && current_user.admin %>
<td class="col-1"><%= link_to "Hide", hide_amol361_path(amol361), method: :put, remote: true, style: "color:#bb7272;" %>
<%= link_to amol361, method: :delete, data: { confirm: "Are you sure?" }, :class => 'delete_item' do %>
<i class="fa fa-trash" ></i>
<% end %>
</td>
<% end %>
</tr>
<% end %>
<% end %>
</tbody>
Right now I am getting the error as undefined method amol361s' for # User::ActiveRecord_Relation:0x00007f5dec19d088.
So, I am trying to get the records followed by usernames, similar to how we gather records based on month.
Any suggestions are most welcome.
Thank you in advance.
From what I understand, you can simply eager load user records if the current user is admin, like this:
#amol361s = Amol361.includes(:user).search(params[:search]).order("created_at ASC")
If you do this, it will be effective to fetch the user data simply by calling association on each member of this relation, like this:
# example:
#amol361s.first.user.username # or whatever the name of username column is
I'm not sure I understood your question correctly though, cause it's a little bit unclear to me.

Ruby on Rails: Destroy action displays an error

If you execute the destroy action, you will get such an error.
URL:http://localhost:3000/listings/test
View
<% #alllistings.all.order(created_at: :desc).each do |listing| %>
<tbody>
<tr>
<th scope="row">
<%= link_to listing_path(listing) do %>
<span class="listing-title"><%= listing.listing_title %></span>
<% end %>
</th>
<td>
<%= link_to "delete",[listing],method: :delete, data: {confirm: "Are you sure?"} if current_user = listing.user %>
</td>
</tr>
</tbody>
<% end %>
Controller
class ListingsController < ApplicationController
before_action :set_listing, only: [:destroy]
def index
#alllistings = current_user.listings
end
def destroy
#listing.destroy
return reedirect_to listings_path, notice: "削除しました", :status => :moved_permanently
end
private
def set_listing
#listing = Listing.friendly.find(params[:id])
end
end
Model
class Listing < ApplicationRecord
validates :listing_title, presence: true
include FriendlyId
friendly_id :listing_title
def should_generate_new_friendly_id?
listing_title_changed?
end
end
rails 5
We are using gem 'friendly_id'.
We also introduced slug.
Please answer me my question.
Please try to use in your view.
<%= link_to "delete",listing_path(listing), method: :delete, data: {confirm: "Are you sure?"} if current_user = listing.user %>

Linking a link from ERB to the control file

I'm trying to make a sort part to my ruby erb list, so far it makes the list then i want a way to sort the list when the click "sort by date". I have no idea where to start?
I'm sure whether to use the href tag or what to use.
<table class="user_display">
<tr>
<th>Name</th>
<th>Date</th>
<th>Friends</th>
</tr>
<% #mentions.each do |name| %>
<tr>
<td><%=h name %></td>
<td><%=h date %></td>
<td><%=h friends %></td>
</tr>
<% end %>
</table>
this isn't the real code but it follows the same ideas with some names changed.
so How do I have a button or link that when they click it reorders the array?
i feel like i should pass something along the lines of
<input class="order" type="button" name="date" value="<%=h params[:orderdate] %>"/>
is this the right idea, if so how do I link to controller file? which has
get '/list' do
#mentions = array_of_names
erb :list
end
any ideas?
Try to add this to the view:
<%= link_to 'Order by date', sort_mentions_path(:order_type => 'date'), :class => 'btn' %>
<%= link_to 'Order by name', sort_mentions_path(:order_type => 'name'), :class => 'btn' %>
In the controller could be something like this:
def sort
if( params[:order_type] == 'name')
#mentions = Mention.order('name')
elsif ( params[:order_type] == 'date')
#mentions = Mention.order('date')
else
#mentions = Mention.all
end
respond_to do |format|
format.html { }
format.json { render json: #mentions }
end
end (Remember to add sort.html.erb with the list view)
And the route:
resources :mentions do
collection do
get 'sort'
end
end
This will put in #mentions the array ordered by date if you have the Object 'Mention':
#mentions = Mention.order(:date)
You don't need to pass any parameter from the view, you can manage the order in the controller

Database values are not showing inside the table while using Ajax in Rails 3

I want to display the database values inside the table using Ajax in Rails.bou i got the following error.
Error:
Template is missing
Missing template users/search, application/search with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "c:/Site/demo2/app/views"
I also added the search.html.erb i removed the error but got the blank page.
Please check my below codes.
views/users/index.html.erb
<%= form_for :user ,:url => {:action => "search" }, remote: true do |f| %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :receipt,:class => "form-control",placeholder:"user number",:onchange => "this.form.submit();" %>
</div>
<% end %>
<div id="search-output-table">
<%= render partial: "search_output_table", locales: {user: #user} %>
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
end
def search
#user = User.find_by_receipt(params[:user][:receipt])
end
end
views/users/_search.js.erb
$("#search-output-table").html("<%= escape_javascript( render(partial: "search_output_table") ) %>");
views/users/_search_output_table.html.erb
<table>
<tr>
<th>User Name</th>
<th>User Email</th>
<th>User Number</th>
</tr>
<tr>
<td><%= #user.name %></td>
<td><%= #user.email %></td>
<td><%= #user.receipt %></td>
</tr>
</table>
I also want remove onchange event and as soon as the value will fill inside text field the action will execute without reload the page as well as the table value will display(initially the table should remain disable/hide).Please help me to resolve this error and add this new scenario.
Well, on request to UsersController#search Rails will by default render app/views/users/search.html.erb, which I assume is empty.
You probably just need to rename views/users/_search.js.erb to views/users/search.js.erb and add following to the controller
def search
#user = User.find_by_receipt(params[:user][:receipt])
respond_to do |format|
format.js
end
end
Also make sure you're passing in #user to the search_output_table template. Like this
render partial: 'search_output_table', locals: {user: #user}
And in 'search_output_table' you should use just user instead of #user.

How do I create a table to display all the instances of my Ruby class using ERB?

My table has the following columns:
<tr>
<th>Number</th>
<th>User</th>
<th>Password</th>
<th>UID</th>
<th>GID</th>
<th>GCOS</th>
<th>Home Directory</th>
<th>Login Shell</th>
</tr>
I have class Student, which looks like this:
class Student
attr_accessor :user_name, :password, :uid, :gid,
:gcos_field, :directory, :shell
attr_reader :count
def initialize(data)
#user_name,#password,#uid,#gid,#gcos_field,#directory,#shell = data
##count = defined?(##count) ? ##count += 1 : 1
end
end
There are about thirty instances of the class under the array map:
#students = datalines.map { |line| Student.new(line.chomp.split(":")) }
A sample element from datalines array is this:
dputnam:x:4185:208:Douglas Vernon Putnam:/users/dputnam:/bin/bash
I haven't been able to get the ##count to function properly either.
My failed attempt at producing a table made all the student names (of my Ruby class incidentally) display horizontally rather than vertically:
<% #students.each do |parameters| %>
<td><%= parameters.user_name %></td>
<% end %>
Any help would be appreciated!
Here's a link to the output if it helps: http://hills.ccsf.edu/~wly3/cs132a/lab4.cgi
Okay the ERB template (I think this is what it is) since it was requested:
<h1>CS132A Lab 4</h1>
<br>
<br>
<table>
<tr>
<th>Number</th>
<th>User</th>
<th>Password</th>
<th>UID</th>
<th>GID</th>
<th>GCOS</th>
<th>Home Directory</th>
<th>Login Shell</th>
</tr>
<tr>
<% #students.each do |parameters| %>
<td><%= parameters.user_name %></td>
<% end %>
</tr>
</table>
<% finish = Time.now %>
<h2>Elapsed time in seconds:<%= (finish.to_f - start.to_f).to_s %></h2>
You have to generate a new <tr> for each student:
<% #students.each do |parameters| %>
<tr>
<td><%= parameters.user_name %></td>
</tr>
<% end %>

Resources