I'm stuck on a tiny problem regarding chartkick. I have a rail app where you can create different currencies. You can then create a expense with a title, a amount and choose the currency from a list and the user_id. The relations are made and working. I have in my user controller something like this :
#user_spendings = #current_user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 15)
#sums_by_currency = Currency.joins(:spendings).
select(:symb, 'SUM(spendings.amount) AS amount').
where(spendings: { id: #user_spendings.map(&:id) }).
group(:symb)
And in my show view (as I want the expense from each user to be shown there) something like this :
<% #sums_by_currency.each do |currency| %>
<%= '%.02f' % "#{currency.amount}" %> <%= "#{currency.symb}" %>
<% end %>
That shows me the sum for each spending depending on the currency.
I would like to use this total and use chartkick to display the spending, with the date when this spending has been created.
I've tried several things already
First I went with this just to see :
<% #sums_by_currency.each do |currency| %>
<%= bar_chart currency.amount %>
<% end %>
Well I have to charts appearing but nothing shows up. Maybe the loop isn't the solution. Then I thought about the .map but I don't really know how to put that in place to be honnest.
I tried this aswell :
<%= line_chart #current_user.spendings.group(:date).sum(:amount) %>
That shows me the total spendings from all the currencies. I have to find out how to split all the currencies in different charts and show only the total amount from each currency.
If anyone can give me a clue I would appreciate it.
Thanks alot.
Ok guys I got it !
Took me 2 days only...
For the one interested in the answer here is what I did. I actually didn't change anything in the controller and I let the #sums_by_currency like it is.
Instead I went for that :
<%= column_chart #current_user.spendings.all.joins(:currency).group('currencies.symb').group_by_month(:date, format: "%B %Y").sum(:amount) %>
Give me all the spendings from the current_user from where I joined the currency that I grouped by symb. Then I grouped everything by month and I get the sum from the amount.
Yeah, you need to pass a set of data to the chart, not lots of individual pieces of data for individual charts (ie what you've got with the loop). Using map to convert your currency-objects to their amounts makes sense eg
<%= bar_chart #sums_by_currency.map{|c| c.amount } %>
or if you need a name something like:
<%= bar_chart #sums_by_currency.map{|c| {name: c.unit, data: c.amount} } %>
Where unit is whatever currency unit eg AUD
Related
I have been learning rails for a while now, but I still have a lot to learn. I recently found this community and I love it. But now, I am at a loss of what to do.
On the genre/show.html.erb page, I want to display other matching genre.title on this page.
From my understanding I should be able to do this from the show page.
This code of course does not work, and I am sure I am off in the wrong direction, if someone could get me back on path, I would be a happy person.
<% if #genre.title == #genre.title %>
<% #genres.each do |genre| %>
<%= link_to genre.title, movie_genre_path(#movie, genre) %>
<% end %>
This is my route:
movie_genre GET /movies/:movie_id/genres/:id(.:format) genres#show
You can filter your genres in your controller.
def show
movie_genre = Movie.find(params[:movie_id]).genre
#genres = Genre.where(genre: movie_genre)
end
If you use your correct database names in this above code, you will have #genres be what you wanted it to be.
I am creating a series of link_to’s, and I am passing some nested information as an array into each URL. My desired outcome looks like so:
?features%5B%5D%5BThick%5D=98&features%5B%5D%5BThin%5D=99
//For some legibility
?features[][Thick]=98&features[][Thin]=99
However, the keys to the hashes inside of the array are not showing up, and I am instead seeing:
?features%5B%5D%5B%5D=98&features%5B%5D%5B%5D=99
//For some legibility
?features[][]=98&features[][]=99
The erb that is creating this series of URLs is here:
<% #products.each |product| do %>
<%= link_to "", new_line_item_path(product_id: product, features: [product.features.each{|feature| {feature.name.to_sym => feature.feature_color_default}}])%>
<% end %>
Is this just a syntactic mistake or is it because I am taking the wrong approach?
**Perhaps this is too much information for this issue but Products have many Features which in turn have many Colors through Feature_Colors.
I'm not sure why the above wasn't working but I made the following changes and am all set. Hopefully the keywords here help someone else if they are making the same mistakes.
First, I pulled the hash creation out into the Product model, like so:
def default_features
list = Hash.new
features.each do |feature|
list[feature.name] = feature.feature_color_default_id
end
return list
end
Then I changed the link_to:
<%= link_to "", new_line_item_path(product_id: product, features: [product.default_features])%>
Working as desired now.
I'm attempting to create a loop which shows stars as reviews are placed for a product, i have it so that it shows the rating as a number however i wish for it to display an image relating to the rating number,
i've currently got
<%=product.no_of_stars.to_i do image_tag "star-on.png" end %>
however it just displays the rating figure and not the number, no doubt I've missed something simple.
I've researched other questions and they state that should be enough for what i want, but of course its not working as expected.
Thanks, Ben.
The above answer is not quite correct. The problem is that Integer#times returns the integer it was called on, so you will still get 5 as the result. Try
<% product.no_of_starts.to_i.times do %>
<%= image_tag "star-on.png" %>
<% end %>
Try this.
<%=product.no_of_stars.to_i.times do image_tag "star-on.png" end %>
You are missing the times method. This is what allows you to run the number as a loop over and over again (super simplification).
I have an object called #events containing about 50 records being pulled from a find condition of my model.
I'm currently displaying the results of the #object in my view like this....
<% for event in #events %>
<p><%= #event.name %></p>
<% end %>
Instead of displaying the entire 50 I would like shrink the set to about 10 records so it displays better on the page.
I cannot use :limit in the find condition since the object is being composed from a variety of loops where after each iteration it adds a few specific records.
So the issue is I have this object #events with 50 records, how can I change the object after its been composed so only the first 10 records remain?
First of all, if you'd like to have pagination, I strongly suggest taking a look at will_paginate
Alternatively, you can do the following to read the first 10 records only.
<% #events.first(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
Or the last 10 records
<% #events.last(10).each do |event| %>
<p><%= event.name %></p>
<% end %>
I didn't test it but you get the point.
are you looking to completely do away with the other 40 or are you just wanting to pull off 10 per page for display purposes. if you are just doing this for display purposes i would look into the will_paginate gem. through its options you could set it so only 10 results per page are shown.
Take a look at will_paginate and kaminari. They both are designed to limit the records retrieved from the database, plus offer helpers for your views to provide the usual number of pages and current page lists.
Will_paginate has been around a while, and is pretty flexible. Kaminari is newer and looks like it has a cleaner interface.
I'm developing a simple rails app for my own use for learning purposes and I'm trying to handle 2 models in 1 form. I've followed the example in chapter 13 of Advanced Rails Recipes and have got it working with a few simple modifications for my own purposes.
The 2 models I have are Invoice and InvoicePhoneNumber. Each Invoice can have several InvoicePhoneNumbers. What I want to do is make sure that each invoice has at least 1 phone number associated with it. The example in the book puts a 'remove' link next to each phone number (tasks in the book). I want to make sure that the top-most phone number doesn't have a remove link next to it but I cannot figure out how to do this. The partial template that produces each line of the list of phone numbers in the invoice is as follows;
<div class="invoice_phone_number">
<% new_or_existing = invoice_phone_number.new_record? ? 'new' : 'existing' %>
<% prefix = "invoice[#{new_or_existing}_invoice_phone_number_attributes][]" %>
<% fields_for prefix, invoice_phone_number do |invoice_form| -%>
<%= invoice_form.select :phone_type, %w{ home work mobile fax } %>
<%= invoice_form.text_field :phone_number %>
<%= link_to_function "remove", "$(this).up('.invoice_phone_number').remove()" %>
<% end -%>
</div>
Now, if I could detect when the first phone number is being generated I could place a condition on the link_to_function so it is not executed. This would half solve my problem and would be satisfactory, although it would mean that if I actually wanted to, say, delete the first phone number and keep the second, I would have to do some manual shuffling.
The ideal way to do this is presumably in the browser with javascript but I have no idea how to approach this. I would need to hide the 'remove' link when there was only one and show all 'remove' links when there is more than one. The functionality in the .insert_html method that is being used in the 'add phone number' link doesn't seem adequate for this.
I'm not asking for a step-by-step how-to for this (in fact I'd prefer not to get one - I want to understand this), but does anyone have some suggestions about where to begin with this problem?
There is a counter for partial-collections:
<%= render :partial => "ad", :collection => #advertisements %>
This
will render "advertiser/_ad.erb" and
pass the local variable ad to the
template for display. An iteration
counter will automatically be made
available to the template with a name
of the form partial_name_counter. In
the case of the example above, the
template would be fed ad_counter.
For your problem of detecting whether a row is the first one or not, you could add a local variable when calling the partial:
<%= render :partial => 'mypartial', :locals => {:first => true} %>
As it would be much easier to detect in the main file, whether a row is the first or not I guess.
Instead of detecting whether a phone number is the first, you could also detect whether a phone number is the only one. If not, add remove links next to all numbers otherwise, do not display the remove link. Note that besides showing/hiding the link, you also need to add code, to prevent removing of the last number by (mis)using an URL to directly delete the number instead of using your form.