How to Show Sum of Column in Rails - ruby-on-rails

I want to display the sum of a column name "money" in my model Earning.
In the rails console, I can easily get the sum I want Earning.sum(:money) and it shows the sum.
earnings_controller.rb
def index
#earnings = Earning.sum(:money)
end
index.html.erb
<p id="notice"><%= notice %></p>
<h1>Earnings</h1>
<table>
<thead>
<tr>
<th>Money</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #earnings.each do |earning| %>
<tr>
<td><%= earning.money %></td>
<td><%= link_to 'Show', earning %></td>
<td><%= link_to 'Edit', edit_earning_path(earning) %></td>
<td><%= link_to 'Destroy', earning, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Earning', new_earning_path %>
It keeps throwing this error
NoMethodError in Earnings#index
What I've tried so far
I am stumped. I've tried changing the index action to #earnings = earnings.sum(:money) and that gave me this error "NameError in EarningsController#index". I also saw a similar problem here but since I think the issue is in my index.html.erb, it didn't help much. As I said earlier the code works in the Rails Console.
Thank you in advance for any help.

So you are not using #earnings in a proper way, in your view you use earnings as a collecion of objects, but in controller #earnings are defined as a sum of money but you are not using it, if you really need this sum, you can set two instance variables fiest #earnings = Earning.all and the second one #money_sum = Earnings.sum(:money) and then you can display somewhere your sum as = #money_sum, then you can iterate by #earnings to create some linka in your view

It looks like you want to do something like this.
First in your controller you want to get all earnings records.
def index
#earnings = Earning.all
end
Then in your view you iterate over all #earnings and spit out earnings.money as single value for each of your record.
If you want to get total of all earnings somewhere, you can do #earnings.sum(:money), which will basically give you single value as total of all earnings - Earning.all.

Related

rails not updating session hash on ajax request without pry

I'm trying to develop a cart system(for a practice e-commerce project) on rails 6.
The code(explaination):
I have a link with class attribute "add_to_cart_link" then I use a jquery to select the elements with the mentioned class and set a on click listener on them. The click listener send an ajax request to 'shopping_experience/add_to_cart'.The control then moves to "add_to_cart" method inside shoppingExperience controller.
the problem is that even though the add_to_cart method is executed, it doesn't update my session hash unless i use "binding.pry"(this is a feature of pry gem which is used for debugging). during pry whenever check the state of the hash(session hash) it's always what its suppose to be and changed when i add some thing to cart.
here is my view template(index.html.erb):
<p id="notice"><%= notice %></p>
<%= link_to 'view cart', display_cart_path %>
<h1>Items</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Category</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #items.each do |item| %>
<tr>
<td><%= item.name %></td>
<td><%= item.price %></td>
<td><%= item.quantity %></td>
<td><%= item.category.title %></td>
<td><%= link_to 'Show', item %></td>
<td> <a class="add_to_cart_link" data-item_id=<%=item.id %> href="#"> add to cart button</a>
</td>
<td><%= link_to 'Edit', edit_item_path(item) %></td>
<td><%= link_to 'Destroy', item, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
here is my custom (myjs.js.erb)
$( document ).ready(function() {
$(document).on('click', 'a.add_to_cart_link', function() {
console.log(this);
console.log($('meta[name="csrf-token"]').attr('content'));
var id = $(this).attr("data-item_id")
console.log(id)
$.ajax({
method: "POST",
headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')},
url: 'shopping_experience/add_to_cart',
data: { item_id: id },
})
});
});
add_to cart method:
def add_to_cart
if !session[:current_cart]
session[:current_cart] = {:shex_id => session[:current_cart_id] }
end
#checks if session hash's current cart key doesn't have params[:item_id] key, value pair
if !session[:current_cart].key?(params[:item_id])
# set {units: 1} as params[item_id] key's value
session[:current_cart][params[:item_id]] = {}
session[:current_cart][params[:item_id]][:quantity] = 1
else
#else increment value of quantity
session[:current_cart][params[:item_id]]["quantity"] = session[:current_cart][params[:item_id]]["quantity"] + 1
#ShexItem.create(item_id: params[:item_id], shopping_experience_id: session[:current_cart_id] )
end
binding.pry
puts(' at to cart method end')
end
so if remove the the bindin.pry from the end my session has isn't changed at all and i do get a "at the end of add to cart method" message in my terminal(even when i remove the binding.pry). this means that the add to card method is indeed called but my session doesn't get updated and if use pry to debug whats wrong it starts to work. I feel it might be related using an ajax request because maybe the session doesnt get updated or refreshed . i really am struggling with this can anyone help?
here is the github repo: https://github.com/HaroonAzhar/ship-shop (i think the repo is public),
if anyone wants to look up the code more.
So I got it to work. I saw a line on my terminal right after the "at the end of at to cart method" message, which said :
"No template found for ShoppingExperiencesController#add_to_cart, rendering head :no_content".
so I don't really know what head :no_content is but i thought it might have un-do/save changes made to session by my method. so at the end of add_to_cart method i redirected to index page with
redirect_to '/'
still quite not sure why template not being found un-do my changes to hash, if anyone could share some light over this in the comments that'll be great! :)

users names not showing in users view

Can anyone tell me why the email addresses are not showing in the users list view below?
<p id="notice"><%= notice %></p>
<h1>Users</h1>
<table>
<thead>
<tr>
<th>Email</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #users.each do |user| %>
<tr>
**<td><%= user.email %></td>**
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New User', new_user_path %>
I'm not familiar with seeing the two asterisks around the element. I'm thinking that might be messing something up. If you want to bold the user's email you could try something like <td><b><%= user.email %></b></td>.
Are you getting any errors anywhere?
If the asterisks are just there to help us see the line of code, and you say that you see the users (and their emails) in the db, I think it could be one of two other relatively minor things.
Whats your controller look like for this view? Are you passing #users to this view? You could try just dumping #users on the page to make sure that it's available.
Is the field on your User model that holds the email called email?

Correct way of conditional rendering within a partial in Rails?

I have created a partial for a LineItem that, in my case, emits a <tr> with a couple of <td>s. This works just fine and dandy.
What I'd want to do then, is use the same partial in different places. The original view has plenty of room, so displaying every cell is ok. But another (a sidebar), has much less space, and I'd only want to display two of the 5 cells.
So the question, then, is what is the correct way of implementing this? I'd like for the "full" version to be the default unless otherwise specified, and only use the limited version if a parameter is passed.
Currently I'd probably use the feature of passing locals to a partial and check if a parameter limited is defined, and if so, skip the last N cells. Am I on a right track, and if so, what kind of a variable should I use (can I use symbols for this)?
Current _line_item.html.erb (that I'm somewhat unhappy with)
<tr>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.title %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price, unit: '€') %></td>
<% unless defined? limited %>
<td class="remove_item"><%= button_to 'Remove', line_item, method: :delete %></td>
<% end %>
</tr>
Edit: Added current version.
Yes, you are on the right track. You can do something like
<%= render 'partial_name', limited: true %>
and then in the partial:
<% limited ||= false %> # More explicit as to what default value is
<tr>
<td><%= line_item.quantity %>×</td>
<td><%= line_item.product.title %></td>
<td class="item_price"><%= number_to_currency(line_item.total_price, unit: '€') %></td>
<% unless limited %>
<td class="remove_item"><%= button_to 'Remove', line_item, method: :delete %></td>
<% end %>
</tr>

How do I show the primary key in the index for ruby on rails?

I'm new to ruby and picking it up a little slower than I would like. I'm working with ruby 3.0. For one of my tables in the database I created I want the primary key to show on the "index" page. I'm having difficulty doing this. I manually put the id in the index view, but it keeps on saying "undefined method `venture_round_id'"
This is what my index.html looks like for the table:
<h1>Listing venture_rounds</h1>
<table>
<tr>
<th>id</th>
<th>company</th>
</tr>
<% #venture_rounds.each do |venture_round| %>
<tr>
<td><%= venture_round.venture_round_id %></td>
<td><%= venture_round.company_id %></td>
<td><% link_to 'show', venture_round %></td>
<td><%= link_to 'Edit', edit_venture_round_path(venture_round) %></td>
<td><%= link_to 'Destroy', venture_round, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
I entered "venture_round_id" and "id" in manually.
This is what my controller looks like for the index:
def index
#venture_rounds = VentureRound.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #venture_rounds }
end
end
I've been researching this problem for two days now and haven't been able to find much about it. I imagine the problem has something to do with accessing the key in its own table. Other parts of my database structure that use venture_round_id as a foreign key work just fine. Any pointers or tips would be greatly appreciated!
Try venture_round.id instead of venture_round.venture_round_id
edit from MrDanA:
a foreign key is usually in the format "table_id" but the table's own primary key is usually just "id". If you ever want to look at what your database tables look like, you can open db/schema.rb to look at the schema. You can also fire up a Rails console and if you just type in the name of your class like VentureRound it will show you its attributes, something like VentureRound(id: integer, company_id: integer, etc)

How can I display data for the current view from a different table

I have two tables:
Chords - |id|chord|name|rating|artist_id|
Artists - |id|artist|
An Artist has many Chords, and thus a Chord belongs to an Artist.
And in the index page for "chords" I want to display chord, name, and rating from Chords table and the artist from the artists table
This is the code for the Chord's index.html.erb:
<table border="1">
<% #chords.each do |chord| %>
<tr>
<td><%= chord.artist.artist %></td>
<td><%= link_to chord.name, chord %></td>
<td><%= chord.rating %></td>
<td><%= chord.created_at %></td>
</tr>
<% end %>
</table>
The error message is:
undefined method `artist' for nil:NilClass
Actually, at first it worked, but when I started to create the "new.html.erb" page and the create and new actions, it stopped working, that's why this is so confusing to me!
Since chort.artist can be null, you should change chord.artist.artist to chord.artist.try(:artist) which is shorthand for
if chord.artist.nil?
nil
else
chord.artist.artist
end
You could use
<td><%= chord.artist.artist unless chord.artist.artist.nil? %></td>
In the view is no the right place to do it but what you need to do is find the artist with the ID given in the CHORDS like this
#currentArtist = Artist.find(:all, :conditions => {:protectora => Chord.artist_id})
Then when you find it by the ID given in the CHORD and save it in to a variable, you can access it like any other variable so:
#currentArtist.artist
Hope it helps.

Resources