Display Country with the most occurrences Rails 3 - ruby-on-rails-3

I have a country model and would like to display the country with the most occurrences, country names are held in the column 'mame', however the country db is pre populated and the relationship is a country
has_many recipes
and recipe
belongs_to country
So far I have
Country.group('name').order('count_name DESC').limit(1).count('name')
but this will not work will it as there are 1 of every country in the table? Do i need to do a count on the number of times the country_id is used? if so what would the syntax be for that? would it be
Recipe.group('country_id').order('count_country_id DESC').limit(1).count('country_id')
or using joins and select
Country.joins(:recipes).select('countries.*, count(country_id) as "country_count"').group(:country_id).order(' country_count desc')
Any pointers appreciated

You can do it by using queries. However, RoR has built in support to achieve the same. It is called Counter Cache.
I can explain here but I think it's better if you follow this screencast.
http://railscasts.com/episodes/23-counter-cache-column
This will give you very good idea how to use counter cache and get what you've tried to achieve.

Related

order a table based on another column attribute

Ok so in my rails project I have these models: pools, memberships, and week_scores
Pool has_many :memberships
Membership has_many :week_scores
WeekScore also has an attribute week:integer that tells what week it is. That way I know if that table is of week 1 or week 6, etc.
WeekScore has an attribute score:integer where I save the points of each user. This makes me think I should change my model name to week_points...
Anyways, I want to show a table of all me the members of a pool sorted by the score they got in a certain week_score.
Just to clarify
The way I get to a ceratin week score right now is
member_score = member.week_scores.find_by(week: 5).score
//member is a member of a pool
For example,
Lets say its week 5,
I want to display the week 5 score of each member of the pool sorted by the score in descending order like so,
David.... 30pts
John..... 28pts
Josh..... 28pts
Mike..... 21pts
...so on
what would be the query i need to achieve this? Ive tried joins but it wont work but im new at this so im pretty sure this is easy to do Im just too newb to know.
Also.. I want to read more about databases and sql for rails so I get more familiar with this. Anyone care to recommend a book?
week5 = Pool.first.memberships.includes(:week_scores)
.where(:week_scores => {week: 5}).order('week_scores.score DESC')
week5.each do |membership|
puts "#{membership.member_name}: #{membership.week_scores.first.score}"
end

Rails order by count on association

I have 2 models. Gif, GifStatistic
gif has_many :gif_statistics
GifStatistics has column called state. It can be either like or dislike
What i want to achieve is to query gifs, but order them in highest count of likes
Something like(Pseudo code)
Gif.joins(:gif_statistics).order(count(gif.gif_statistics.state))
How do i achieve this?
Try this query.
Gif.joins(:gif_statistics).select("*, count(gif_statistics.state) as state_count").order("state_count desc")
My personal recommendation is that you create two new fields in the gif model so that you can store the count of like and dislike as and when its created so that you don't have to do such a complex query. Placing the counter cache would improve the speed.

Generate random resource ID's with prefix?

I have a simple Rails 3 invoicing application with the following models:
Brand
Client
Invoice
A brand has many invoices, clients have many invoices and invoices belong to clients and brands. Basically the brand is the company creating the invoice, client is the recipient of the invoice and the invoice the the actual invoice.
I am trying to work out the best way of having a simple random reference number for each invoice that's prefixed by something unique per brand.
I'm thinking of adding a invoice_prefix to the brand table. Then the brands would each have a three digit prefix, such as DAN-.
What would be the best way of adding the brands prefix followed by a 5 digit random number to a column in the invoice table?
I'm open to suggestions of better ways of doing this!
The end result I would like is for each invoice to have a unique reference similar to DAN-98372.
I think the best way would be to add the prefix column to the brand table and then create an before_create action for invoices that inserts a random number after the brand prefix. I'm just not sure on the best way to do this.
before_create :generate_reference
private
def generate_reference
self.invoice_number = self.brand.prefix
end
The above code correctly pulls in the brand prefix, but I'm unsure how to add a random 5 digit number afterwards.
I think something like <%= rand(1000..9999) %> would work, but I'm not sure how to add that to the brand prefix in the before_create.
I'm not very familiar with after_create methods so any advice would be appreciated!
you can use
https://github.com/patdeegan/integer-obfuscator
or https://github.com/namick/obfuscate_id
that way you can hide how many invoices you really have and it will be unique
From the provided info, its a case of polymorphic association. refer http://guides.rubyonrails.org/association_basics.html.
In the code provided, u should call 'generate_reference' 'before_create' rather than 'after_create' since u want the assigned values to be saved. specifying 'after_create' will go infinite loop.
Generate random data resources
https://github.com/wemersonblend/fakejs

Single Table Inheritance (STI)... Multi Table Inheritance (MTI)... Polymorphic Associations

So I have found MANY posts on these subjects but none have answered my (probably very novice) question. I am brand new to Rails this month but I have been programming in OOL for a little while. I think my question might span multiple subjects about Ruby on Rails. I don't mind reading multiple blogs or tutorials to peace this all together.
I have 4 location models. Each have a "Name" attribute.
Country (has_many :states)
State (belongs_to :country has_many :counties has_many :cities, :through => :counties)
County (belongs_to :state has_many :cities)
City
My end goal is to have an autocomplete textbox for city, county, state. The user will select a country to narrow down the results. For example, the user will type in "SA" and the autocomplete textbox will show:
Kansas
Arkansas
Santa Clara County, California
San Jose, Santa Clara County, California
etc.
So I can easily return the text that I want displayed. Each model has something like:
def location_name
// the display name of this model. For example we want the County Model to return "Santa Clara County, California"
"#{name}, #{state.name}"
end
Solutions I tried to research:
Active Record Query Interface to make one select statement across the multiple tables. My goal would be to search across multiple models and get a single list of objects with the name containing the search text.
STI - Maybe create a Location model which all can inherit from but I couldn't find any basic tutorial online that include models with different attributes for each. Do I "generate" one model with all the fields that all 5 would need then just delete them from the auto generated .rb file? I assume I will then be able to use Location.where("name like ? and country_id = ?", params[:search], params[:country_id]) and get a full list of all location which fit the search parameters.
MTI - I looked at this since I'm not a big fan of excess columns in the DB that are mostly blank. For example :country_id would only be used by states. So it would be null for all counties and cities, etc. But all the tutorial seem to imply that STI would be the better way to go.
Polymorphic Associations - I just started looking into this a few hours ago. I found something about ":polymorphic => true" and I read another article that talked about a subclass feature.
I have spent quite a few days looking into the "right" way of doing this according to Ruby. I'd really like to learn and incorporate all that ruby has to offer. Thanks for any thought!
maybe you can watch this video for your further development too.
http://railscasts.com/episodes/88-dynamic-select-menus
one-to-many for your case should be alright i guess..
like this country has many states and the according state has many of cities.
correct me if im wrong ##

ActiveRecord - Retrieve one record for each association

Merchant has_many Shops
Shop belongs_to Merchant
i.e. One merchant (Starbucks) can have many shops locations.
I'm using Gecoder to get the nearby shops, e.g. #shops = Shop.near("Times Square").
I would like to return only 1 record for each merchant only. I.e. #shops only contain 1 Starbucks, 1 Subway, but is a collection.
Sorry I've been Googling and searching on SO to no avail. Perhaps I'm not using the right word to describe what I want. Thanks in advance.
To answer what you should be googling for, joined or combined queries within a scope will probably solve what you are looking to do. If you build a scope with :or logic combining queries, one each for each shop, limited to the first record, you should get what you are looking for.
I won't pretend that I understand Geocoder or advanced scopes enough to do this, but I found an example that shows this approach in another problem:
named_scope :or, lambda { |l, r| {
:conditions =>
"annotations.id IN (#{l.send(:construct_finder_sql,{:select => :id})}) or " +
"annotations.id IN (#{r.send(:construct_finder_sql,{:select => :id})})"
}}
This comes from this SO question: Combine two named scopes with OR (instead of AND)
Hope this helps you find the solution.
I googled a bit more and stumbled on group by for SQL.
If I have 4 shops belonging to 2 merchants near a location called "Raffles Place", within 1 kilometer.
Calling Shop.near("Raffles Place",1) returns 4 shops.
If I add a group to Shop.near("Raffles Place",1).group(:merchant_id), only 2 shops are returned.
This can be used with other conditions too, such as Shop.where(:featured=>true).group(:merchant_id) to only show 1 shop per featured merchant.