Ruby on Rails: Fetch database result and search through results - ruby-on-rails

I have a set of IDs for a table called "brands". I want to fetch the name column for each record in the brand table without having to re-query the database using Brand.find(brand_id). Instead, is there a way to store the database results into a variable and query the variable?
Thanks.

if you already collected the records in a var #brands, you can use
name = #brands.find {|b| b.id == brand_id}.name
not a query

This will return an array of all Brands for a brand_id
Brand.find(:all, :conditions => ["brand_id = ?", brand_id])
For a collection of brand_ids
Brand.find(:all, :conditions => ["brand_id IN (?)", [brand_id1, brand_id2]])
HTH

You can write a method in your model brand.
def get_associated_brand
b = self.brand_id
brand = Brand.find(b).name
end
From your view just call this method so that in your view you ll get brand name instead of ID like
brand.get_associated_brand
instead of
brand.brand_id

About what was commented on #Harsh Gupta's answers, maybe
#filtered_brands = Brand.where(id: <some_id>)
Then you can access all info of each brand in a regular each loop.

Related

Get Unique records per attribute in Active Record

I have Student model and I would like to get one record per term_id (one of the attributes).
Student.select(:term_id).distinct
works but the result is an array of term_ids, not the objects themselves - which is what I would like to get
Try this:
Student.pluck("DISTINCT id, term_id")
Student.select("DISTINCT term_id, `students`.* ")
Incase if you are using older versions of ruby (< 2.3.8),
Student.find(:all, :select => "DISTINCT(term_id), `students`.*")
or if you want id alone,
Student.find(:all, :select => "DISTINCT(term_id), id")
where students is your table name. You will get array of objects.

Test for "not equal" on array using Controller.where() possible?

Is it possible to use the '.where()' controller method to select all db-elements that are not equal to an array consisting of ID numbers?
I can easily use the '.where()' controller method to select all db elements that are equal to a list of ID numbers stored in an array:
user_event_ids = current_user.event_items.pluck(:event_id)
#user_events = Event.where(id: user_match_ids)
But I can't seem to find a way to select all db-elements that have ID numbers which ar enot in the 'user_event_ids' array.
I've tried (with no luck):
#non_user_events = Event.where('user_id not in :arr', {arr: user_event_ids})
#non_user_events = Event.where(''user_id != ?', user_event_ids)
Both do not work and cancel with errors. Any help is appreciated!
This should be the correct syntax for what you are after:
Event.where('user_id NOT IN (?)', user_event_ids)
Given excluded_ids is an Array containing the IDs you want to exclude
If you are using Rails 4:
Event.where.not(user_id: excluded_ids)
If you are using Rails 3:
Event.where('user_id NOT IN (?)', user_event_ids)
If you are using Squeel
Event.where{user_id.not_in excluded_ids}
Here is another syntax:
Event.find(:all, :conditions => ['user_id not in (?)', user_event_ids])

Rails: Get only certain attributes of submodel with method 'attributes'

Is there a way to get only certain fields of a foreign model like this:
#user = User.find(:first, :select => ['`users`.`id`, `users`.`nickname`, `users`.`birthdate`, `users`.`sex`'], :conditions => ['`users`.`id` = ?', id])
city = #user.profile.city.attributes
With attributes I retrieve all attributes of my city model. I'd like to get only some. Something like:
city = #user.profile.city.attributes[:name, :postcode]
Is it possible by keeping the syntax as simple as above? I want to use attributes to receive a Hash.
thanks a lot.
You could do this if you don't mind that it picks out fields after the SQL returns everything:
#user.profile.city.attributes.select{|k,v| ["name","postcode"].include?(k)}
It's not possible to select fields of foreign models when chaining in the way you have. The only way would be to do a query on the City model:
City.where(:profile_id => #user.profile.id, :select => ...)
You cannot give arguements after attributes otherwise it will raise ArguementError. In this case you can use inner join to fetch the records.
city = #user.profile.city.pluck(:name, :postcode)

Given an Object form a query with 100s of items. How can I find an item in the object w/o having to re-query the db?

Given an object like contacts:
Contact.rb (id, fname, lname, key_tag)
#contacts = Contacts.where(:user_id => #user.id)
Given #contacts comes back with 1000s of records in that one DB query. How can I then get/see if a object exists in #contacts that matches a given 'key_tag'.
I tried:
#contacts.where(:key_tag => 'def12')
But that requeries the database which is exactly what I want to avoid. Ideas? Thanks
what you Have is an Relation there. So adding the other where changes the relation and queries that data back. It should be lazily loaded. So in your code
Contact.rb (id, fname, lname, key_tag)
#contacts = Contacts.where(:user_id => #user.id)
If you don't touch #contacts, it shouldn't even hit the DB. But once you try to get data from it, it will then be executed and data comes back. If you are going to show all of them, you could use something like #all to return them as an array, and then use Array#select to search through it. Depending upon the speed of the system and/or your db, it might be more efficient to the DB do the select.
#contacts = Contacts.where(:user_id => #user.id).all
#contacts_with_key = #contacts.select { |c| c.key_tag == 'def12' }
You can use Enumerable find method:
#contacts.find {|c| c.key_tag == 'def12'}
Try Enumerable#find_all
#contacts.find_all {|a| a[:key_tag] == 'def12'}
Or if you want to only find first one(given that key_tag is unique)
#contacts.find {|a| a[:key_tag] == 'def12'}
be sure to:
include Enumerable

rails where() sql query on array

I'll explain this as best as possible. I have a query on user posts:
#selected_posts = Posts.where(:category => "Baseball")
I would like to write the following statement. Here it is in pseudo terms:
User.where(user has a post in #selected_posts)
Keep in mind that I have a many to many relationship setup so post.user is usable.
Any ideas?
/EDIT
#posts_matches = User.includes(#selected_posts).map{ |user|
[user.company_name, user.posts.count, user.username]
}.sort
Basically, I need the above to work so that it uses the users that HAVE posts in selected_posts and not EVERY user we have in our database.
Try this:
user.posts.where("posts.category = ?", "Baseball")
Edit 1:
user.posts.where("posts.id IN (?)", #selected_posts)
Edit 2:
User.select("users.company_name, count(posts.id) userpost_count, user.username").
joins(:posts).
where("posts.id IN (?)", #selected_posts).
order("users.company_name, userpost_count, user.username")
Just use the following:
User.find(#selected_posts.map(&:user_id).uniq)
This takes the user ids from all the selected posts, turns them into an array, and removes any duplicates. Passing an array to user will just find all the users with matching ids. Problem solved.
To combine this with what you showed in your question, you could write:
#posts_matches = User.find(#selected_posts.map(&:user_id).uniq).map{ |user|
[user.company_name, user.posts.size, user.username]
}
Use size to count a relation instead of count because Rails caches the size method and automatically won't look it up more than once. This is better for performance.
Not sure what you were trying to accomplish with Array#sort at the end of your query, but you could always do something like:
#users_with_posts_in_selected = User.find(#selected_posts.map(&:user_id).uniq).order('username DESC')
I don't understand your question but you can pass an array to the where method like this:
where(:id => #selected_posts.map(&:id))
and it will create a SQL query like WHERE id IN (1,2,3,4)
By virtue of your associations your selected posts already have the users:
#selected_posts = Posts.where("posts.category =?", "Baseball")
#users = #selected_posts.collect(&:user);
You'll probably want to remove duplicate users from #users.

Resources