I have a Mail model with the following schema:
t.string "mail"
t.integer "country"
t.boolean "validated"
t.datetime "created_at"
t.datetime "updated_at"
And I want to find the top 5 countries in the database, so i go ahead and type
#top5 = Mail.find(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5 )
This will tell me the groups(i need an order by i dont know how to write)
#top5 = Mail.count(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5 )
This will tell me how many mails are in each group
Im wondering if i can group and count in just one go
Try:
Mail.count(:group => 'country', :conditions => ['validated = ?', 't'])
I'm not sure count accepts :limit though.
EDIT:
I think this is more readable:
Mail.count(:group => :country, :conditions => {:validated => true})
With Rails 3 you can simplify it further:
Mail.where(validated: true).count(group: :country)
You can order by fields in the group - in this case only :country would be valid:
Mail.where(validated: true)
.order(:country)
.count(group: :country)
You can also order by the count, using "count_all":
Mail.where(validated: true)
.order("count_all desc")
.count(group: :country)
You can also limit the number of groups returned. To do this you must call limit before calling count (because #count returns ActiveSupport::OrderedHash):
Mail.where(validated: true)
.order("count_all desc")
.limit(5)
.count(group: :country)
Updated syntax for Rails 4:
Mail.where(validated: true)
.group(:country)
.count
Mail.find(
:all,
:select => 'count(*) count, country',
:group => 'country',
:conditions => ['validated = ?', 't' ],
:order => 'count DESC',
:limit => 5)
This should give you records that have a country attribute and a count attribute.
I too had to group data with city name and showing count of how many rows are there for each city with specific condition. So this is how I did:
CityData.where(:status => 1).group(:city_name).count
Output of this was:
{:Mumbai => 10, :Dublin => 7, :SF => 9}
Related
I have a model with an array column. So I'm basically saving languages as an array to Postgres. For example, driver_language =["English", "Spanish", "French"]
In my Query, I want to select all vehicles where submitted_driver_language ["English", "Spanish"] is included in driver_language. Or at least one element of the submitted driver_language array is included in the driver_language column which is an array. How can I add that condition to the query below? Any help will be appreciated
Vehicle.where(:vehicle_type => vehicle_type, :active => true, :company_activated => true, :capacity => number_of_people.to_i..Float::INFINITY)
Use arel_table.
#vehicle = Vehicle.where(:vehicle_type => vehicle_type, :active => true, :company_activated => true, :capacity => number_of_people.to_i..Float::INFINITY)
avehicle = #vehicle.arel_table
#required_result = #vehicle.where(avehicle[:driver_language].matches('%#{"English", "Spanish"}%'))
What about a regex?
Vehicle.where('driver_language ~* ?', 'english|spanish')
I have some trouble with mongoid:
test "Test candidate" do
User.create(:id => 1, :sex => User::Male, :country => 1, :city => 1)
User.create(:id => 2, :sex => User::Female, :country => 1, :city => 1)
User.create(:id => 3, :sex => User::Female, :country => 1, :city => 1)
user = User.not_in(:id => [2]).second
assert_not_equal(user.id, 2)
end
Test failed. I've tried to use where(:id => {'$nid' => [2]}), but it have same effect.
What is wrong? How to use "not in" condition with mongoid?
PS, "second" is ok, with "first" test passed, because id=1
Try this query:
user = User.not_in(:_id => [2]).second
In MongoDB primary key has name _id. Mongoid tries to be friendly and partially hides this fact from the developer by aliasing it to id in the object model. But when you do queries, it cannot tell if you want primary key _id or some completely ordinary field id.
user = User.where(:id.nin => [2,3,4,5])
This is as per mongoid official doc : http://mongoid.org/en/origin/docs/selection.html
it's my first question in stackoverflow.
In my application i have a real time section, to see the movements of the web. Its an online newspaper and ths section shows: new article, new comment, new vote, new debate.....all what is happening on the web.
I have this code:
def index
#objects = Article.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :published => true })
#objects = #objects + Debate.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Event.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Comment.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now), :active => true })
#objects = #objects + Vote.find(:all, :conditions => { :created_at => (Time.now-48.hours)..(Time.now) })
#objects.sort! {|x,z| x.created_at <=> z.created_at}
#objects.reverse!
end
I load all in the last 48 hours. I've been reading about caching in rails because I think that this isn't my solution.
What can I do to load this list more fast? Because now it takes 7...or 8 seconds...
Thanks for all :D
few notes:
find(:all) is deprecated. use where() instead.
instead of doing 5 db calls migrate them into one db call (create a sql query for that if needed).
make sure you index the dates columns in your tables.
don't sort sort and reverse. instead replace y <=> x so it will sort the way you need.
hope it helps..
I have a join table, which have 3 parameters. I want to update it, using a where-clause, something like this: (which obviously is not correct)
Grid.update(:page_id => #page_id,:thing_id => #thing_id,:number => #number ).where(:page_id => #page_id, :number => #number ).first
I need to find the record with mathing page_id and number, and then update the thing_id.
Thanks!
Jakob
Grid.where(:page_id => #page_id, :number => #number).first.
update_attributes(:page_id => ...,: thing_id => ..., :number => ...)
In rails 2.3.8 I'm trying to order a query having first the post that has the most comments AND votes.
I've tried to add a new method to the Post model as:
def interestingness
self.comments_count + self.votes_count
end
post_of_the_moment = find(:all, :conditions => ["submitted_at BETWEEN ? and ?", from, to],
:order => :interestingness,
:limit => 10
)
but this code gives me a Unknown column error.
I also tried this
post_of_the_moment = find(:all, :conditions => ["submitted_at BETWEEN ? and ?", from, to],
:order => "SUM(comments_count+votes_count) DESC",
:limit => 10
)
this doesn't give me errors but puts as result only 1 row that has 0 comments and 0 votes.
What am I doing wrong?
Thanks,
Augusto
Try this:
post_of_the_moment = find(:all, :select => '*, comments_count + votes_count AS total', :conditions => ["submitted_at BETWEEN ? and ?", from, to], :order => "total DESC", :limit => 10)
I'd also see if you can optimize it be replacing the * above with only the fields you actually need. Also check your MySQL indexes are ok, as you want to avoid a full table scan etc. to sum the counts.
Figured out the error I was doing: the SUM() in the order was grouping the result set.
This works:
post_of_the_moment = find(:all, :conditions => ["submitted_at BETWEEN ? and ?", from, to],
:order => "(comments_count+votes_count) DESC",
:limit => 10
)
Still don't know why I cannot use as a sort field the interestingness method I created.