How to use group/group_by in Rails properly for Chartkick? - ruby-on-rails

I am trying to display completed tasks done my user's friends.
I have a function friend? that returns a boolean value
For Bar chart I need to use count
<%= bar_chart #completed_tasks.count%>
Here is how I try to get the desired data:
#completed_tasks = Task.where(completed: true).select{|task| friend?(task.user_id)}
And after all I need to group it by user_id. How can I do it properly?
I have tried adding the following options:
.group(:user_id)
.group_by(:user_id)
.group_by(&:user_id)
but i don't get any data represented in bar chart. What am I doing wrong?

The problem was in the fact that .group() works with ActiveRecord Relations. Task.where(...) is an ActiveRecord Relation, while select returns an array. Here is my solution:
arr = Task.where(completed: true).select{|task| User.find(task.user_id).is_friend?(current_user)}
#completed_tasks = Task.where(id: arr.map(&:id)).group(:user_id)

Related

Rails 4 update_all and set value from another field

I need to do some bulk updates in some models and set value of a field as value of another field.
Right now I can do that with raw sql like this:
ActiveRecord::Base.connection.execute("UPDATE `deleted_contents` SET `deleted_contents`.`original_id` = `deleted_contents`.`id` WHERE `deleted_contents`.`original_id` is NULL")
This is working fine, however I need to do this using ActiveRecord query interface due to many reasons.
I tried:
DeletedContent.where(original_id: nil).update_all(original_id: value_of_id_column)
For value_of_id_column I tried :id, self.id, id, etc, nothing works. What should I set for value_of_id_column to get the original query generated by rails? Is this possible, or using the raw sql is the only solution?
Also I do not want to iterate over each record and update. This is not a valid solution for me:
DeletedContent.where(original_id: nil).each do |deleted_content|
update_each_record
end
I'm pretty sure you cannot obtain that query by passing a hash to update_all.
The closest to what you want to obtain would be:
DeletedContent.where(original_id: nil).update_all("original_id = id")

active record how do I specify a column after a join?

I'm trying to make an sql query using activerecord and I'm having a hard time specifying a specific column from multiple joined tables.
for instance in sql
select go.id, sequence.name, sequence.id from sequence join (goterms,...) on ...
this is not beautiful sql but my point is that I'm able to specify which .id I want returned
in activerecord I'm doing this:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa)
.select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name)
.distinct
I want to be able to get id from :Goterm but :Taxa and :Foreigndb also use id as a column in the database so i'm getting uninformative errors that I assume stem from this issue when I do the following.
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa)
.select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name,:id)
.distinct
What is the correct way to just specify that I want Goterm.id?
edit - Here is the error:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'Goterm.id' in 'field list'
when I run:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass,:genus, :interpro_desc,:description,:dbname, :read_depth, :name,'Goterm.id').limit(5).offset(0).dresults = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname, :read_depth, :name,'Goterm.id').limit(5).offset(0).distinct
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus, :interpro_desc,:description,:dbname,:read_depth, :name, 'sequences.id')
.distinct
It turns out that ilan's answer is correct, however be sure that everything is lower case. I was using 'Goterm.id' to make the selection when it needs to be 'goterm.id'
If anyone else runs into this, I also ran into difficulties grabbing the goterm.id data out of the returned query objects. Each time I called object.id on that return set it would give me something different from what I was expecting. I think the attribute I was expecting was being obscured by something else. To get the data I needed I did the following:
results = Sequence.joins(:Foreigndb,:Goterm,:Taxa).select(:header,:taxaclass, :genus,:interpro_desc,:description,:dbname,:read_depth, :name).distinct
firstRes = results[0]
firstRes.attributes['id']

How to get a unique set of values for a given field of array

I am working on integrating Solr search with a RoR app. The solr returns docs which have a field productTaxonomyName.
In the controller corresponding to search I retrieve docs from solr and push them into a #products array. I want to get the set of unique values of the productTaxonomyName field in a variable within the controller. How can I do that.
Will this work:
#taxons = #products.map {|p| p.productTaxonomyName }
Thanks
#taxons = #products.map(&:productTaxonomyName).compact.uniq
Btw, why dont you get them right from Solr.

how to order a result that I have got using select statement in rails

I have the following in my controller to get a bunch of data to show in the view
#orders = Order.select{|order| order.email==#user.email}.select{|order| order.clip_status==true}.select{|order| order.dc>0}.select{|order| ((Time.now.to_date..(CustomVideo.find_by_order_id(order.id).created_at.to_date+30.days)).count-1)<0}
Now I need to order it according to the created date.
I tried the following and got errors:
#orders = Order.select{|order| order.email==#user.email}.select{|order| order.clip_status==true}.select{|order| order.dc>0}.select{|order| ((Time.now.to_date..(CustomVideo.find_by_order_id(order.id).created_at.to_date+30.days)).count-1)<0}.order('created_at DESC')
And I am getting an error. How do I solve this?
undefined method `order' for []:Array
Your problem comes from misuse of select - you use select as if ActiveRecord::Relation was usual array - and select used that way indeed returns Array instance, which doesn't respond to ActiveRecord scopes. I suggest you to use where when it's possible and to use select with block (which returns Array) after all AR scopes are applied, like this:
#orders = Order.where('your conditions').order('created_at DESC').select { |order| order.dc > 0 }
BTW, actually it's possible to replace last select also with where (which is much more efficient), like this:
Order.where('dc > ?', 0)

How to get table column value?

I write follow code to get one record from the table webeehs:
webeehs_result = Webeeh.find(:all, :conditions=>["webeeh_project_id=#{project_id}"])
Then I want to get one column value from this record, how could I do?
For example, the column name is webeeh_date.
first of all, never EVER write code like that. Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. If you must do conditions, then do it like this:
:conditions => ["webeeh_project_id = ?", project_id]
if you have a Project model, you should rename the webeeh_project_id column from your Webeeh model into project_id and have an association in your Project model like has_many :webeehs
Then, you won't need to call that find anymore, just do a p = Project.find(id) and then p.webeehs will return the webeehs you need.
the result will be an array which you can iterate through. And to get your webeeh.webeeh_date member, just call it like this:
result.each do |webeeh|
date = webeeh.webeeh_date
end
webeehs_result = Webeeh.findwebeeh_dates
is enough to get all columnn values.
For a different method and performance issues check the following: http://www.stopdropandrew.com/2010/01/28/finding-ids-fast-with-active-record.html
webeeh_result will usually be an array of results for the database.
You can iterate throughit using
webeehs_result.each do |webeeh|
# use "webeeh.webeeh_date" to access the column_name or do whatever you want with it.
end

Resources