This query return an Array on users variable:
users = #users.flat_map {|b| b.followees_by_type('aged') }
I need apply this filter to users:
olds = users.any_of({ :image_filename.ne => nil }, { :yt_video_id.ne => nil}).all_of(:active.ne => false)
But I can not apply because is an Array.
Is possible change to mongoid criteria this array?
Any other solution?
Note important! I can not modify output class type b.followees_by_type('aged')
As per my comment, you should use #users which is a Mongoid::Criteria instead of users which is just an Array.
Related
I am trying to perform a sort_by on a hash, but whenever I have a nil value I get:
comparison of DateTime with nil failed
My goal is to perform a nil check (.present?) on x[:last_posted_at] inside the sort_by method. Is that possible? Example code:
posts = [
{ "name"=>"Alice", "last_posted_at"=> some_datetime },
{ "name"=>"Bob", "last_posted_at"=> nil},
{ "name"=>"Clark", "last_posted_at"=> some_datetime - 1}
]
# expected result
posts.sort_by.{ |x| x[:last_posted_at] } #compare only if value is not nil
#=> [{"name"=>"Alice", "last_posted_at"=> some_datetime},
# {"name"=>"Clark", "last_posted_at"=> some_datetime - 1},
# {"name"=>"Bob", "last_posted_at"=> nil}]
I looked into the sort_by documentation and some of the posts here in stackoverflow, but I cannot find my answer. Any help or links are welcome! Thanks in advance!
I like Schwern's approach. But if there are more records without a date then another option might be to separate record without dates from the records with dates and only sort thoses with a date like this:
posts
.partition { |v| v['last_posted_at'] } # separate by date presence
.tap { |v| v.first.sort_by! { |v| v['last_posted_at']} } # only sort entries with a date
.flatten # combine into one list again
Use presence to return the value or nil, and || to return a default value if it is blank.
# Something sufficiently old to be older than any other time.
nil_time = Time.at(0)
posts.sort_by.{ |x|
x[:last_posted_at].presence || nil_time
}
Note: DateTime is deprecated.
I have a Convo table and a GroupMeeting table that both are associated with a Msg table.
I want to find all the instances where the current_user has convos or group_meetings with msgs, combine the two, and then show both together to the user in order of the last msg.created_at
Here I have defined both:
#convos = Convo.includes(:msgs).where("sender_id = ? OR recipient_id = ?", current_user, current_user).where.not(:msgs => { :id => nil }).merge(Msg.order(created_at: :desc))
#group_meetings = current_user.group_meetings.includes(:msgs).where.not(:msgs => { :id => nil }).merge(Msg.order(created_at: :desc))
And then combined them together:
#convos = #convos + #group_meetings
What I can't figure out is how to now sort them by msg.created_at
I have tried the following:
#convos = (#convos + #group_meetings).sort_by(&:"#{msg.created_at}")
#convos.order('msg.created_at DESC')
These all seem to be server-side sorting though. How can I sort these based off the join table, after the array has been created?
Please let me know if I need to supply any other details. Thank you!!
You can try the following:
(#convos + #group_meetings).sort_by { |item| item.msgs.minimum(:created_at) }
I'm trying to retrieve multiple values from a database into a single variable and return the whole thing. Here is what I am doing
my_hash = {
'name' => 'John'
'current_location' => 'Sweden'
}
Now I need to go into database and retrieve all records and store them into a single variable, and then i need to add that variable into my_hash so I can return the whole thing. How would I do that?
Example:
last_names = Names.where('first_name = ?', 'John').select('last_name').last_name
my_hash.add(last_names)
return my_hash
Now that above does not works, can somebody tell me proper way to achieve this?
are you trying to do the following?
my_hash = {
'name' => 'John'
'current_location' => 'Sweden'
}
my_hash['last_names'] = Names.where('first_name = ?', 'John')
.select('last_name')
.map { |name| name.last_name }
# or shorthand version .map(&:last_name)
return my_hash
Updated
# get name objects from the database
# add select as an optimization if desired
last_name_list = Names.where('first_name = ?', 'John')
# get an array of only the last_name fields
last_names = last_name_list.map { |name| name.last_name }
# assign the array to the new hash key 'last_names'
my_hash['last_names'] = last_names
see http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-map for documentation on map, note that map and collect are the same
another example
names = Names.where('updated_at >= ?', Date.parse('2013-01-01'))
# get an array of 'full names'
full_names = names.map do |name|
"#{name.first_name} #{name.last_name}"
end
I have a table called audits which has a column 'changes' storing data in the form of hash
I would like to retrieve all entries with the following conditions:
- auditable_type = 'Expression'
- action = 'destroy'
- changes = { :EXP_SUBMISSION_FK =>'9999992642'}
I first tried the following code which returns me with nothing:
#deleted_history = Audit.find(:all, :conditions => ["auditable_type =? AND action = ? AND changes = ?",'Expression', 'destroy' , { :EXP_SUBMISSION_FK =>'9999992642'} ])
I then tried the following code which retrieves all entries in the 'audits' table with auditable_type = 'Expression' and action = 'destroy'.
I then loop through the resultset and discards all entries where EXP_SUBMISSION_FK is not equal to 9999992642. The code below returns me 5 entries/records
#deleted_history = Audit.find(:all, :conditions => ["auditable_type =? AND action = ?",'Expression', 'destroy' ])
#deleted_history.each do |test|
if test.changes['EXP_SUBMISSION_FK'] != 9999992642
#deleted_history = #deleted_history.reject { test }
end
end
I would like to know where did I go wrong with the first code example and whether there is a way of retrieving all entries with the aforementioned conditions in a much simpler way.
Thanks a lot for your help.
i'd do:
#deleted_history.select!{|hist| hist.changes['EXP_SUBMISSION_FK'] == '9999992642'}
One potential cause of failure is that you're looking for 9999992642 but you state before the value is '9999992642'
You just use something like below. I am storing element_values as a hash and i am selecting records based on the key/value pair.
scope :find_by_field_values, lambda {
|field_name, field_value|
(where("element_values like ?", "%\"#{field_name}\":\"%#{field_value}%"))
}
just try this based on your scenario.
Consider the following code which is to be thrown at an AR find:
conditions = []
conditions[:age] = params[:age] if params[:age].present?
conditions[:gender] = params[:gender] if params[:gender].present?
I need to add another condition which is a LIKE criteria on a 'profile' attribute. How can I do this, as obviously a LIKE is usually done via an array, not a hash key.
You can scope your model with hash conditions, and then perform find on scope with array conditions:
YourModel.scoped(:conditions => conditions).all(:conditions => ["profile like ?", profile])
Follwing is ugly but it works
conditions = {} #This should be Hash
conditions[:age] = params[:age] if params[:age].present?
conditions[:gender] = params[:gender] if params[:gender].present?
conditions[:profile] = '%params[:profile]%' if params[:profile].present?
col_str ="" #this is our column names string for conditions array
col_str = "age=:age" if params[:age].present?
col_str+= (col_str.blank?)? "gender=:gender" :" AND gender=:gender" if params[:gender].present?
col_str += (col_str.blank?) 'profile like :profile' : ' AND profile like :profile' if params[:profile].present?
:conditions=>[col_str , conditions]
When you call your active record find, you send your conditions string first, then the hash with the values like :
:conditions => [ "age = :age AND gender = :gender AND profile LIKE :profile", conditions ]
that way you can keep doing what you are doing :)