Company model: There is aa attribute name and company has_many users.
Users model: User belongs to company.
Query:
After the query execution, below is my result.
users = {1360=>[#<User id: 2183, company_id: 1360, name: "XYS">, #<User id: 2184, company_id: 1360, name: "XYS1">], 1361=>[#<User id: 2185, company_id: 1361, name: "ABC">]}
In users object, there is one more column that is company_name which is fetch in query as alias, because I want only company_name not other attributes.
users = {1360=>[#<User id: 2183, company_id: 1360, name: "XYS", company_name="One">, #<User id: 2183, company_id: 1360, name: "XYS", company_name="One">], 1361=>[#<User id: 2185, company_id: 1361, name: "ABC", company_name="Two">]}
Here is the my desired output.
(Key would be company_name and its velue will be array of users info(name and id))
users = {"One"=>[["XYS", 2183], ["XYS1", 2184]], "Two"=>[["ABC", 2185]]}
How can I do that. Because when I try to replace the key(id) with name throughs an error
Try this
users.map{ |_,array| [array.first.company_name, array.map{ |a| [a.name, a.id] }] }.to_h
Related
Here is the scenario, I have these objects. Let's assume that this is a User:
The object came from:
#user = User.all
User Object
[<#User id: 1, firstname: "John", lastname: "Pond">,<#User id: 2, firstname: "Paul", lastname: "Rich">,<#User id: 3, firstname: "Jasmine", lastname: "Ong">]
How can I move one object up, for example I want to move User.id == 2? The result I want is shown below.
[<#User id: 2, firstname: "Paul", lastname: "Rich">,<#User id: 1, firstname: "John", lastname: "Pond">,<#User id: 3, firstname: "Jasmine", lastname: "Ong">]
I already got the answer. Here is what I made to made my question above worked.
#users = User.all
user_ids = User.pluck(:id)
user_ids.delete(2)
new_user_ids = [2]
user_ids.each do |id|
new_user_ids << id
end
#users.sort_by { |user| new_user_ids.index(user.id) }
And this made perfect!
We can also do it in a way like this:
Add a new method to Array. lib/rails_extensions.rb
class Array
def swap!(a, b = a - 1)
self[a], self[b] = self[b], self[a]
self
end
end
Then add this in config/environment.rb
require 'rails_extensions'
So we can use the method swap! for arrays and it will swap the object with the one before it. We can do something like this:
#users = User.all #[<#User id: 1>, <#User id: 2>]
user_id = #users.rindex {|user| user.id == 2}
#users = #users.swap!(user_id) #[<#User id: 2>, <#User id: 1>]
is this too ugly?
hash = [{ id: 1}, {id: 2}, {id: 3}]
hash.unshift(hash.delete(hash.select {|h| h[:id] == 2 }.first))
=> [{:id=>2}, {:id=>1}, {:id=>3}]
Query of searchkick get wrong result.
I have this one record in db:
2.2.0 :047 > Product.first
#<Product id: 1, title: "Ball", description: "<p>Ball</p>\r\n", price: 10, material: "lalala", created_at: "2015-04-21 04:30:53", updated_at: "2015-04-21 04:30:53", preview: "images__1_.jpg", count: 20>
in controller Product and action search i have this code:
def search
#products = Product.search "*", where:
{
count: 10..18
}
end
and after this, a get result, that the with this values, count is exist.
But in db count = 20. And all time, get wrong result. I don't know why?
I get not correct result, 'cause i don't have hash, in model and need reindex of Model.
In model:
def search_data
{
count: count,
price: price,
title: title,
category_id: categories.map($:id)
}
end
and after that, in rails console wrote:
Product.reindex
So here's the method I want to test:
def self.by_letter(letter)
where("lastname LIKE ?", "#{letter}%").order(:lastname)
end
Quick question here, what exactly does the percent sign after #{letter} do? Something to do with formatting?
Here's part of the spec that tests that method:
context 'method "by_letter"' do
it 'returns and ordered list by letter' do
theon = Contact.create!(
firstname: "Theon",
lastname: "Greyjoy",
email: "tgreyjoy#ironprice.com"
)
rob = Contact.create!(
firstname: "Rob",
lastname: "Stark",
email: "rstark#winterfell.com"
)
tyrion = Contact.create!(
firstname: "Tyrion",
lastname: "Lannister",
email: "tlannister#kingslanding.com"
)
result = Contact.by_letter("S")
expect(result).to include("Snow")
end
end
And here's the logs I get for an output after running said test (oh, bare in mind, earlier in the spec I created a "Jon Snow", and he should pop up before "Stark" alphabetically):
Failures:
1) Contact method "by_letter" returns and ordered list by letter
Failure/Error: expect(result).to include("Snow")
expected #<ActiveRecord::Relation [#<Contact id: 1, firstname: "Jon", lastname: "Snow", email: "lordcommander#nightswatch.com", created_at: "2014-11-14 17:17:55", updated_at: "2014-11-14 17:17:55">, #<Contact id: 3, firstname: "Rob", lastname: "Stark", email: "rstark#winterfell.com", created_at: "2014-11-14 17:17:56", updated_at: "2014-11-14 17:17:56">]> to include "Snow"
Diff:
## -1,2 +1,3 ##
-["Snow"]
+[#<Contact id: 1, firstname: "Jon", lastname: "Snow", email: "lordcommander#nightswatch.com", created_at: "2014-11-14 17:17:55", updated_at: "2014-11-14 17:17:55">,
+ #<Contact id: 3, firstname: "Rob", lastname: "Stark", email: "rstark#winterfell.com", created_at: "2014-11-14 17:17:56", updated_at: "2014-11-14 17:17:56">]
What am I missing? Shouldn't my test pass because I return a collection that includes a string I specified? Is there some complication because it's not a regular array but some sort of proxy array? What do I need to do to get my test to pass?
Your result is an ActiveRecord::Relation object. So you should do as below :-
expect(result).to include(rob)
rob has the last name as "Stark", thus Contact.by_letter("S") will include rob in the filtered list.
Try expect(result.first).to include("Snow")
You can also say (preferably):
expect(result.first.lastname).to eq("Snow")
Maybe somebody has an idea how I could solve following problem:
I have a Model and want to query it.
def MyModel < ActiveRecord::Base
# instance method
def all
my_models = MyModel.all
my_models.?? # order my_models ActiveRecord::Relation, that the instance which calls the .all instance method is at first position, and the rest is sorted somehow,..whatever.
end
end
How could I solve that?
EDIT:
Example:
MyModel has a name.
I have four instances of MyModel
MyModel.all => #<ActiveRecord::Relation [#<MyModel id: 1, name: "name1">, #<MyModel id: 2, name: "name2">, #<MyModel id: 3, name: "name3">, #<MyModel id: 4, name: "name4">]>
And I want now:
MyModel.find(1).all => #<ActiveRecord::Relation [#<MyModel id: 1, name: "name1">, #<MyModel id: 2, name: "name2">, #<MyModel id: 3, name: "name3">, #<MyModel id: 4, name: "name4">]>
MyModel.find(2).all => #<ActiveRecord::Relation [#<MyModel id: 2, name: "name2">, #<MyModel id: 1, name: "name1">, #<MyModel id: 3, name: "name3">, #<MyModel id: 4, name: "name4">]>
MyModel.find(3).all => #<ActiveRecord::Relation [#<MyModel id: 3, name: "name3">, #<MyModel id: 1, name: "name1">, #<MyModel id: 2, name: "name2">, #<MyModel id: 4, name: "name4">]>
I believe this accomplishes what you're asking.
def all
self.class.order("case when id = #{id} then 0 else id end")
end
A possible solution would be taking advantage of the fact that an ActiveRecord::Relation instance responds to many of the Array instance methods:
def all
ary = self.class.order(:id)
ary = ary.unshift(self)
ary.uniq
end
However this returns an instance of Array so you can't keep appending additional scopes. Up to you to decide whether that's acceptable in your case.
I am trying to populate a ruby on rails select box from a database query, the data comes from 3 tables.
My query
#data = Session.all :include => { :term => :courses }
Object
!ruby/object:Session
attributes:
created_at: 2010-06-17 22:12:05
term_id: "15"
updated_at: 2010-06-17 22:12:05
id: "3"
course_id: "1"
attributes_cache: {}
term: &id003 !ruby/object:Term
attributes:
number: "1"
start_date: 2010-06-17
created_at: 2010-06-17 22:12:05
updated_at: 2010-06-17 22:12:05
id: "15"
attributes_cache: {}
courses:
- &id001 !ruby/object:Course
attributes:
created_at:
updated_at:
course_name: Beginner
id: "1"
date:
course_type: Programming
attributes_cache: {}
what i am trying to do is to have the term number followed by the data data and then the course
like this
1 01-09-10 Programming Beginners
The id for the option would be the session_id
any ideas ?
Thanks
Alex
in your erb template you can put the following code withing you form:
<%= select("session","id", #data.map{|d| ["#{d.term.number} #{d.term.start_date} #{d.course.course_type} #{d.course.course_name}",d.id]} %>