How to create an value array for a specific key in ruby hash? - ruby

There are user and user_level models in our rails app. In user_level there is a field called user_group_id. The relationship is userhas_manyuser_levels. We would like to generate an array of the user_group_id (in user_level) for a given user_id.
For a given user_id, its user_levels could be retrieved as :
u = User.find(user_id)
ul = u.user_levels
There may be multiple user_levels for a user. How to create an array of user_group_id from ul with ruby map (or some other ruby method(preferable ruby))? thanks.

Try this,
user = User.find(user_id)
user.user_levels.pluck(:user_group_id)
or this,
user.user_levels.map(&:user_group_id)
The first makes a separate database query selecting just the :user_group_id. For example, in MySQL it would call SELECT user_levels.user_group_id ....
The second collects the :user_group_id from the fetched user_levels.

You are indeed looking for map
user_group_ids = ul.map{|x| x.user_group_id}
Or with the shorthand:
user_group_ids = ul.map(&:user_group_id)
You might also want to have only different ids and no nils
user_group_ids = ul.map(&:user_group_id).uniq.compact

Related

How to get table name for a simple Sequel Dataset object?

Ie, given a dataset object ds = DB[:transactions].where{updated_at > 1.day.ago} - no funny joins and stuff going on - how could I fetch the table name (:transactions) ?
If you want the first table in the dataset, you can use ds.first_source.
If you want it as a string you can do:
ds.first_source_table.to_s
If you want a symbol, just omit .to_s
Based on the example provided, I would do something like this.
ds.klass.name
That will return a string with the name of your table.

apply group on associated attributes ruby on rails by using kickchart to show the geo chart

I need to apply group on associated attributes to apply it on pie_chart which is the method of kick chart so I just need to fetch the associated object attribute like
= pie_chart array.group(:user)
it returns the user object but I need to apply group on user attribute which is username so please if anybody has solution of this answer me.
You can use Enumerable#group_by (http://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-group_by)
Example :
array.group_by { |linker| linker.user.username }
It will create a Hash with the usernames as keys and Array of linkers as values

How to use Sequel to select one field from database

I am using Sinatra and Sequel with PostgreSQL.
After authentication, I want to welcome the user by printing their name but I cannot get only the value of the user's name from the database, it comes out as a hash.
The query is:
current_user = DB[:users].select(:username).where('password = ?', password).first
and the resulting piece of data is:
Welcome, {:username=>"Rich"}
which looks rather weird, I would prefer it to read "Welcome, Rich".
What am I doing wrong here? I tried the same query without 'first" at the end and that does not work either.
You can either pull the (single) column you selected out of the Hash you are given:
current_user = DB[:users].select(:username).where('password=?', password).first[:username]
Or you can map your results to an array of usernames and pull the first:
# Using a hash in the filter method is simpler than SQL placeholders.
current_user = DB[:users].filter(password:password).select_map(:username).first
But the best way is to get only the user you care about, and then get the name:
# Using [] on a dataset returns the first row matching the criteria
current_user = DB[:users][password:password][:username]
Try Sequel::Dataset#get. Also, as Phrogz points out, Sequel::Dataset#where can take a hash (it will securely escape values to prevent injection attacks).
current_username = DB[:users].where(password: password).get(:username)
There's also Sequel::Dataset#where_single_value, which is optimized for this exact situation:
current_username = DB[:users].select(:username).where_single_value(password: password)

How to check included ID or not?

I have ActiveRecord collection and a I want to check my ID in it.
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id)
and I check
#items_user_id.include?(params[:id])
returned nil
What's wrong?
UPD 1 : What I need - param[:id] contains id of Item. The user can edit the items created by them only. And I want to check whether the item identifier in the identifier pool items user.
In short: you are comparing Apples to Oranges.
Long Answer:
#items_user_id = Item.select("DISTINCT user_id").where(:user_id => current_user.id) this line will return Array of Item elements.
params[:id] would possibly be String or Integer so it would not be found in the Array.
The select you do executes this query:
SELECT DISTINCT user_id FROM items WHERE user_id = ?
That will yield either nothing, or a single row with just the user_id.
What do you really want?
Try to collect the ids from the array obtained and then check..
#items_user_id.map(&:id).include?(params[:id])
Make sure the datatype of ids(string) matches with params[:id]

Interacting With Class Objects in Ruby

How can I interact with objects I've created based on their given attributes in Ruby?
To give some context, I'm parsing a text file that might have several hundred entries like the following:
ASIN: B00137RNIQ
-------------------------Status Info-------------------------
Upload created: 2010-04-09 09:33:45
Upload state: Imported
Upload state id: 3
I can parse the above with regular expressions and use the data to create new objects in a "Product" class:
class Product
attr_reader :asin, :creation_date, :upload_state, :upload_state_id
def initialize(asin, creation_date, upload_state, upload_state_id)
#asin = asin
#creation_date = creation_date
#upload_state = upload_state
#upload_state_id = upload_state_id
end
end
After parsing, the raw text from above will be stored in an object that look like this:
[#<Product:0x00000101006ef8 #asin="B00137RNIQ", #creation_date="2010-04-09 09:33:45 ", #upload_state="Imported ", #upload_state_id="3">]
How can I then interact with the newly created class objects? For example, how might I pull all the creation dates for objects with an upload_state_id of 3? I get the feeling I'm going to have to write class methods, but I'm a bit stuck on where to start.
You would need to store the Product objects in a collection. I'll use an array
product_collection = []
# keep adding parse products into the collection as many as they are
product_collection << parsed_product_obj
#next select the subset where upload_state_ud = 3
state_3_products = product_collection.select{|product| product.upload_state_id == 3}
attr reader is a declarative way of defining properties/attributes on your product class. So you can access each value as obj.attribute like I have done for upload_state_id above.
select selects the elements in the target collection, which meet a specific criteria. Each element is assigned to product, and if the criteria evaluates to true is placed in the output collection.

Resources