where for querying an array attribute in rails model - ruby

I have a user model with an array of roles.
u=User.first
u.roles = ['admin']
v=User.last
u.roles = ['admin', 'member']
How do i query to fetch all users with admin role?
Edit:
roles is a serialized array for the user model
User Model:
serialize :roles
Migration:
add_column :users, :roles, :string, default: []

Depends on what "roles" means:
If it is an association as in
class User < ActiveRecord::Base
has_many :roles
end
Then you look up the role and fetch all users:
Role.find_by_name("admin").users
or roles is just a column and it is serialised, in which case you can instantiate all users (slow)
User.all.select { |u| u.roles.include? "admin" }
Or query the database directly which is more complex and depends on the adapter.
My opinion: I would avoid using serialised columns, when relations can do. They are cumbersome in every way: Forms, Searches, Selects...

Another way is using scopes:
Model user.rb:
class User
scope :admins, -> () { where("roles #> ?", '{admin}')}
scope :by_roles, -> (roles) { where("roles #> ?", "{#{roles.join(', ')}}") }
end
Scoped calls, with results
Admins:
3.0.0 :001 > User.admins
User Load (0.4ms) SELECT "users".* FROM "users" WHERE (roles #> '{admin}') /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, account_uuid: "0812df2d-58ed-4231-aca5-ec7708a156bb", email: "admin#example.com", password_digest: [FILTERED], first_name: "Admin", last_name: "Admin" remember_token: nil, remember_token_expires_at: nil, roles: ["user", "admin"], created_at: "2021-12-02 11:51:50.684788000 +0000", updated_at: "2021-12-02 11:51:50.684788000 +0000">]>
Users by_roles within single role:
3.0.0 :002 > User.by_roles(['user'])
User Load (0.5ms) SELECT "users".* FROM "users" WHERE (roles #> '{user}') /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, account_uuid: "0812df2d-58ed-4231-aca5-ec7708a156bb", email: "admin#example.com", password_digest: [FILTERED], first_name: "Admin", last_name: "Admin", remember_token: nil, remember_token_expires_at: nil, roles: ["user", "admin"], created_at: "2021-12-02 11:51:50.684788000 +0000", updated_at: "2021-12-02 11:51:50.684788000 +0000">, #<User id: 2, account_uuid: "7a09830d-bfde-45eb-abeb-4b305a7bb374", email: "user_1#example.com", password_digest: [FILTERED], first_name: "User", last_name: "Adviseman", remember_token: nil, remember_token_expires_at: nil, roles: ["user"], created_at: "2021-12-02 17:40:12.172547000 +0000", updated_at: "2021-12-02 17:40:12.172547000 +0000">, #<User id: 3, account_uuid: "a0044954-6ad0-4d8f-9681-bd5dfcfa72b7", email: "user_2#example.com", password_digest: [FILTERED], first_name: "User", last_name: "Adviseman", remember_token: nil, remember_token_expires_at: nil, roles: ["user"], created_at: "2021-12-02 17:40:12.583594000 +0000", updated_at: "2021-12-02 17:40:12.583594000 +0000">, #<User id: 4, account_uuid: "7d26e5d5-beaf-48bd-ad98-f53044a7182b", email: "user_3#example.com", password_digest: [FILTERED], first_name: "User", last_name: "Adviseman", remember_token: nil, remember_token_expires_at: nil, roles: ["user"], created_at: "2021-12-02 17:40:12.847412000 +0000", updated_at: "2021-12-02 17:40:12.847412000 +0000">]>
Users by_roles within multiple roles:
3.0.0 :003 > User.by_roles(['user', 'admin'])
User Load (0.6ms) SELECT "users".* FROM "users" WHERE (roles #> '{user, admin}') /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 1, account_uuid: "0812df2d-58ed-4231-aca5-ec7708a156bb", email: "admin#example.com", password_digest: [FILTERED], first_name: "Admin", last_name: "Bezugliy", remember_token: nil, remember_token_expires_at: nil, roles: ["user", "admin"], created_at: "2021-12-02 11:51:50.684788000 +0000", updated_at: "2021-12-02 11:51:50.684788000 +0000">]>

Related

How to get id from associated relation rails?

Can i get an id from associated relation?
for example i have relation between user and skill through user_skill
In User model, i write like this:
class User < ApplicationRecord
has_many ::skills, through: :user_skills
end
In UserSkill model
class UserSkill < ApplicationRecord
belongs_to :skill
belongs_to :user
end
I can call them like this
User.find(1).skills
but there is no user_skill id in there.
how to include id of user_skill? because everytime i call
User.find(1).skills
it will be like this
[#<Skill id: 3, name: "Google Analytics", description: "Google Analytics\r\n", created_at: "1970-01-04 11:20:00.000000000 +0000", updated_at: "1970-01-04 11:20:00.000000000 +0000", category: "software">, #<Skill id: 8, name: "Adobe After Effect", description: "Test", created_at: "2022-08-21 02:58:25.561498000 +0000", updated_at: "2022-08-21 02:58:25.561498000 +0000", category: "software">, #<Skill id: 1, name: "Microsoft Office", description: "Word, Excel, PowerPoint", created_at: "1970-01-02 03:46:40.000000000 +0000", updated_at: "1970-01-02 03:46:40.000000000 +0000", category: "software">]
You can do:
user_skills = User.find(1).user_skills.include(:skill)
user_skills.each do |user_skill|
user_skill.id #=> the user_skill id
user_skill.skill #=> the actual skill
end

What is inside my ruby array?

So I have an Array filled of what exactly?
myArray = [ #<Follower id: 1, username: "Prep Bootstrap", imageurl: "http://pbs.twimg.com//profile_images/2825468445/2a4...", user_id: "thefonso", follower_id: "2397558816", created_at: "2014-05-21 15:29:03", updated_at: "2014-05-21 15:29:03">, #<Follower id: 2, username: "JAVA Developer", imageurl: "http://pbs.twimg.com//profile_images/2825468445/2a4...", user_id: "thefonso", follower_id: "2352382640", created_at: "2014-05-21 15:29:05", updated_at: "2014-05-21 15:29:05">,
Follower id: 3, username: "JAVA Developer two", imageurl: "http://pbs.twimg.com//profile_images/2825468445/2a4...", user_id: "thefonso", follower_id: "2352382641", created_at: "2014-05-21 17:29:05", updated_at: "2014-05-21 17:29:05"> ]
Now I have many more of these inside this array with consecutive ids, etc..I'm confused by the #< >, is this an array of hashes? What am I looking at exactly? What is this an array of?
It looks like ActiveRecord's Followers class instances. Plus, it looks like you named your model improperly (with Rails practices, it should be named Follower).
Get the class of one of the objects and you'll know it
puts myArray[0].class

Split array. Ruby

Could you help me please with some problem?
I have array from database like this
str = Hiring::Tag.all
Hiring::Tag Load (0.1ms) SELECT `hiring_tags`.* FROM `hiring_tags`
=> [#<Hiring::Tag id: 1, name: "tag1", created_at: "2013-12-10 11:44:39", updated_at: "2013-12-10 11:44:39">,
#<Hiring::Tag id: 2, name: "tag2", created_at: nil, updated_at: nil>,
#<Hiring::Tag id: 3, name: "tag3", created_at: nil, updated_at: nil>,
#<Hiring::Tag id: 4, name: "wtf", created_at: "2013-12-11 07:53:04", updated_at: "2013-12-11 07:53:04">,
#<Hiring::Tag id: 5, name: "new_tag", created_at: "2013-12-11 10:35:48", updated_at: "2013-12-11 10:35:48">]
And I need to split this array like this:
data:[{id:1,name:'tag1'},{id:2,name:'tag2'},
{id:3,name:'tag3'},{id:4,name:'wtf'},{id:5,name:'new_tag'}]
Help me please!
if you use ActiveRecord 4.0
Hiring::Tag.pluck(:id, :name).map{ |id, name| {id: id, name: name} }
One possible solution:
Hiring::Tag.all.map {|h| {id: h.id, name: h.name} }
See the documentation for map.
You can try below code.
Hiring::Tag.all.inject({}) { |h, f| h[f.name.to_sym] = f.value; h }
OR
Hiring::Tag.all.map { |f| [f.name.to_sym, f.value] }]

Loop through array in search for elements with certain attributes - with as short/concise code as possible

My check_processors method should go through an array of processors (provided by the processor_list argument) and output a new array, containing the same processors.
The processor_list argument is either nil or an array of processors, e.g.:
[
<Processor _id: 5158713883c336812100007f, _type: nil, created_at: 2013-03-31 17:24:08 UTC, updated_at: 2013-03-31 17:24:08 UTC, name: "my_mapping_processor", value: {"something"=>{"something_else"}}, type: "mapping", order: 0>,
<Processor _id: 5158713883c3368121000080, _type: nil, created_at: 2013-03-31 17:24:08 UTC, updated_at: 2013-03-31 17:24:08 UTC, name: "my_presentation_processor", value: {"something"=>{"something_else"}}, type: "presentation", order: 1>,
<Processor _id: 5348143r83c93641210d0080, _ty...
]
The check_processors method should verify that 2 specific processors (recognized by the type attribute of a processor) exists. If no processor with type == "mapping" is found, create_mapping_processor should it. Or if no processor with type == "presentation" is found, create_presentation_processor should create it.
The code below works, but the job it is doing is so simple that it must be achievable with less code.
def check_processors(processor_list = nil)
processors = []
if processor_list == nil
mapping_processor = create_mapping_processor
presentation_processor = create_presentation_processor
processors.push(mapping_processor)
processors.push(presentation_processor)
else
mapping_processor_exists = false
presentation_processor_exists = false
processor_list.each do |processor|
processors.push(processor)
mapping_processor_exists = true if processor.type == "mapping"
presentation_processor_exists = true if processor.type == "presentation"
end
if mapping_processor_exists == false
mapping_processor = create_mapping_processor
processors.push(mapping_processor)
end
if presentation_processor_exists == false
presentation_processor = create_presentation_processor
processors.push(presentation_processor)
end
end
processors #=> [<Processor _id: 5158713883c336812100007f, _type: nil, created_at: 2013-03-31 17:24:08 UTC, updated_at: 2013-03-31 17:24:08 UTC, name: "my_mapping_processor", value: {"something"=>{"something_else"}}, type: "mapping", order: 0>, <Processor _id: 5158713883c3368121000080, _type: nil, created_at: 2013-03-31 17:24:08 UTC, updated_at: 2013-03-31 17:24:08 UTC, name: "my_presentation_processor", value: {"something"=>{"something_else"}}, type: "presentation", order: 1>, <Processor _id: 5348143r83c93641210d0080, _ty...]
end
def create_mapping_processor
mapping_processor = Processor.new(:name => "my_mapping_processor", :value => {"something"=>{"something_else"}}, :type => "mapping", :order => 0)
mapping_processor
end
def create_presentation_processor
presentation_processor = Processor.new(:name => "my_presentation_processor", :value => {"something"=>{"something_else"}}, :type => "presentation", :order => 1)
presentation_processor
end

How i can find uniq records on base of some attribute in sort_by rails

Hi i have these records how i can find unique records in sort_by methods block
my array is like this
[#<Post id: 1, name: "ali", team_elo: 0, team_name: "solo", created_at:
"2012-12-09 16:11:17", updated_at: "2012-12-11 03:39:43">,
#<Post id: 2, name: "ramiz", team_elo: nil, team_name: "roko", created_at:
"2012-12-11 03:40:31", updated_at: "2012-12-11 03:40:31">,
#<Post id: 3, name: "ramizrt", team_elo: nil, team_name: "joko", created_at:
"2012-12-11 03:40:47", updated_at: "2012-12-11 03:40:47">,
#<Post id: 4, name: "lee", team_elo: nil, team_name: "roko", created_at:
"2012-12-11 03:41:15", updated_at: "2012-12-11 03:41:15">]
how i can sort this array on base of unique team_name.The result should like this
[#<Post id: 1, name: "ali", team_elo: 0, team_name: "solo", created_at:
"2012-12-09 16:11:17", updated_at: "2012-12-11 03:39:43">,
#<Post id: 2, name: "ramiz", team_elo: nil, team_name: "roko", created_at:
"2012-12-11 03:40:31", updated_at: "2012-12-11 03:40:31">,
#<Post id: 3, name: "ramizrt", team_elo: nil, team_name: "joko", created_at:
"2012-12-11 03:40:47", updated_at: "2012-12-11 03:40:47">]
Thanks
You could do something like:
arr = arr.uniq { |x| x.team_name }
or its brother
arr.uniq! { |x| x.team_name }
which will set arr to only the elements you want.

Resources