In one of the views (erb) I have the following code
collection_select(:wp_article, :wp_site_id, WpSite.find_by_sql(["SELECT wp_sites.* FROM wp_sites, users_wp_sites, users WHERE users_wp_sites.user_id = users.id and users_wp_sites.wp_site_id = wp_sites.id and username= ?", session[:cur_username]]), :id, :name,
{:prompt => true})
This lists the site names that are accessible by the current user (cur_username) in a drop down list, for example
Google.com
Facebook.com
Twitter.com
Now I need to display the number of times that the user has accessed these sites in the same drop down list, like this:
Google.com (32)
Facebook.com (68)
Twitter.com (21)
How can I modify the query to include the count together with the site name?
(I know how to get the count in a subquery within the same query posted above, but do not know how to pass name of site (:name) and count (the new count I will get in the subquery) to the drop down list as one complete string.)
Managed to solve it in this way:
<%= collection_select(:wp_article, :wp_site_id, WpSite.find_by_sql(["SELECT wp_sites.id, CONCAT(wp_sites.name, ' (', (select count(*) from wp_articles where wp_articles.wp_site_id = wp_sites.id and wp_articles.author = users.username and published = 1), ')') name FROM wp_sites, users_wp_sites, users WHERE users_wp_sites.user_id = users.id and users_wp_sites.wp_site_id = wp_sites.id and username= ?", session[:cur_username]]), :id, :name, {:prompt => true}) %>
In the main SQL query I am using CONCAT (it is a MySQL backend) to append the count to the name and keeping the attribute name "name" (so that it is referenced by symbol :name).
Related
I've this select in my form:
<%= select_tag :x, options_from_collection_for_select(#dmj, :id, :name, :selected), {class: "form-control"} %>
but when I load the page, the option whose value is set in db is not selected.
The symbol :selected comes from a SQL query in the controller and if I try to replace the :name with :selected in the options_from_collection_for_select, I can see that its value is correct.
Also, if I manually set the integer in the options_from_collection_for_select the corresponding option is selected.
Why do I not succeed in selecting the option with the symbol?
EDIT:
My query is making a join to retrieve the selected from a Join table. Here's the query:
#dmj = DiscoveryModeInjury.find_by_sql("SELECT D.name, D.id, L.discovery_mode_injury_id AS selected
FROM
discovery_mode_injuries D
LEFT OUTER JOIN
link_dismodeinj_hospitalizations L
ON
D.id = L.discovery_mode_injury_id
WHERE
flag = 'disc'
ORDER BY
D.name")
If I have understood correctly Akash Srivastava's suggestion, the query should return the DiscoveryModeInjury id field? How..? thanks.
Make sure your query for :selected returns an :id field. Basically, the selected option in options_from_collection_for_select() should be of the same field as the value field of the same, which is :id in your case. Many of us make this mistake of keeping the result of selected as an object of the collection.
I am trying just to display unique values in the year. This is what I tried so far
= select_tag("year", options_for_select(Car.all.uniq.map{|c|[c.year, c.year]}))
I do know that uniq is for an array. The other thought was to do a validation for uniqueness but the client doesn't want that.
Here you can use select field to get unique dropdown list, check the below code for help:
<%= f.select :year, options_for_select(Car.all.map {|p| [ p.year ]}.uniq, "Select Year"),:prompt => "Select Year",:required => true %>
You are using uniq on Car model. You should map from the collection all the years, then remove duplicates:
= select_tag("year", options_for_select(Car.all.map(&:year).uniq))
In my controller, I get movies with:
movies = Movie.active.includes(:likes).references(:likes).where("likes.user_id = ?", user.id).joins(:collections).active.uniq
I then order and filter them:
#movies = movies.order(query_order).offset(offset).limit(limit + 1)
This output in an PG:Error: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
I quickly found at that you have to select the fields you order by. So I added .select("movies.*, likes.*") to the query.
movies = Movie.select("movies.*, likes.*").active.includes(:likes).references(:likes).where("likes.user_id = ?", user.id).joins(:collections).active.uniq
It works fine except now Paperclip messes up big time. The HTML gets rendered exactly the same as before, but somehow the image doesn't show/process.
=image_tag movie.cover.url(:expanded), :class => "expanded"
When I remove .select("movies.*, likes.*") and .uniq from the query it has duplicate items, but the images work fine.
Because I joined movies with likes it both retrieved the movie.id and the likes.id.
This this paperclip helper couldn't cope with two id's so it randomly picked the likes id.
=image_tag movie.cover.url(:expanded), :class => "expanded"
As a result wrong paths got created: iE. /movies/system/007/movie_with_id_01_image.jpg.
I had to change my select clause, now excluding the likes.id.
.select("movies.*, likes.*")
.select("movies.*, likes.column_a, likes.column_b, ... , likes.column_x")
Now it finally worked again.
Say I have a Users table, and each user has a country_id (the list of countries is stored in another table).
I want to display a list of each country and how many members it has, ie:
Canada: 16
Romania: 12
USA: 9
I was using some raw SQL, but the move to postgres was messy, so I'd like to use a cleaner implementation. Is there a nice 'railsy' way to go about getting said list?
This should return a hash with country_id => count pairs:
#users_by_country = User.group(:country_id).count
#=> { 1 => 104, 2 => 63, ... }
The generated SQL query looks like this:
SELECT COUNT(*) AS count_all, country_id AS country_id FROM `users` GROUP BY country_id
And in your view:
<% #countries.each do |country| %>
<%= country.name %>: <%= #users_by_country[country.id] %>
<% end>
though you have not provided any detail . so its hard to answer exaclty, but may be this will help
User.group(:country_id).count
If you have a Countries model and you want to do it a little differently so that it is more human readable you could use .map.
Countries.map{|o| { Country: o.name, members: o.members.count } }
Obviously you need to have the associations. If countries is just a field on User then this will not work.
BR
In my view I have a form with a text_field_tag that takes an int, and returns only the timesheets whose timesheet.user_id match that int
<%= text_field_tag("user_id", params[:user_id]) %>
And then I have a bunch of users, these users have a name user.name and an id user.id.
I have a method in the controller called pending_approvals that when given the user id, narrows my list down to a specific users objects.
if params[:user_id].present?
#time_sheets = #time_sheets.joins(:user).where("users.id IN (?)", params[:user_id])
end
So what I am having an issue with, is I am not sure how to populate my select box with a list of users names. And then when submitted I need it to give the users id to that method. What is the best way of doing this?
If I understand correctly is you want a collection dropdown list to detail all users and thier id. You can do:
<%= collection_select :user, :user_id, #users, :name, :id, :prompt => true %>
Where :text_method is method which called on #users members will return text that you'd like to appear in dropdown.
The ApiDocs breaks it down, and this is how it is set up:
object = User
method = user_id
collection #users
value_method = id
text_method = name
option = prompt => true