object with latest date mongoid - ruby-on-rails

I have 2 objects with created_at attribute.
I want to know the query with Which of these two objects is the most recent date
object 1:
#<User _id: 504726081d41c809e5000003, _type: "User", created_at: 2012-09-05 10:14:33 UTC >
object 2:
#<User _id: 503fb40f1d41c8255a000007, _type: "User", created_at: 2012-08-30 18:42:24 UTC >
Edited
This 2 object are inside array: something like:
[#<User _id: 504726081d41c809e5000003, _type: "User", created_at: 2012-09-05 10:14:33>, #<User _id: 503fb40f1d41c8255a000007, _type: "User", created_at: 2012-08-30 18:42:24>]
I can not use .last. I need use lastest date.
Thank you very much

I'd say:
User.order_by([:created_at, :desc]).limit(1).first #useful to include other ordering conditions
Or:
User.desc(:created_at).limit(1).first
Since your edit:
array.max_by{|u| u.created_at}

Related

rails check_box_tag to include existing values of from array of records

The following tag in a nested form
<%= check_box_tag "friend_ids[]", ff.id, #contentrestrictions.friends.include?(ff.id) %>
is handling the following array of records
>> #contentrestrictions
[
#<Contentrestriction id: 29, usercontent_id: nil, friend_id: nil, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">,
#<Contentrestriction id: 30, usercontent_id: nil, friend_id: 2, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">,
#<Contentrestriction id: 31, usercontent_id: nil, friend_id: 4, created_at: "2019-04-28 10:55:32", updated_at: "2019-04-28 10:55:32">]
Even though
class Contentrestriction < ApplicationRecord
belongs_to :friend, optional: true
#contentrestrictions. followed by any of friend_id, friend_ids both appended with or without [] all lead to NoMethodError: undefined method for Array.
how can this include function get a proper array to work with?
the issue is in this line:
#contentrestrictions.friends.include?(ff.id)
you are comparing a friend object with a friend id, you could use pluck to get the friend ids, or you could just compare the objects:
#contentrestrictions.friends.include?(ff)
this will make a query for the .friends and you could remove this query by pre-loading the friends association, e.g. eager_load(:friends) or includes(:friends)

Rails - how to automatically uniq joins method?

This question is based on this: Rails, why joins returns array with non-uniq values?
Let say I get non uniq array by .joins() method:
City.joins(:locations)
# => [#<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">]
I can make records uniq by using
City.joins(:locations).group('cities.id') # or simpler
City.joins(:locations).uniq
# => [#<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">]
How can I make .joins() method returns uniq records by default?
You could try overriding the .joins method for the models you need, but I would suggest just writing a scope, e.g.
scope :unique_locations, -> { joins(:locations).uniq }
Then just call City.unique_locations. It's cleaner and more readable that way.
Generally overwriting methods should be done only when you're sure you won't need it 'the old way', and it makes sense. Plus, when you say City.joins(:locations) the reader expects default behaviour, and returning something else will cause chaos and confusion.
You can define has_many macro, with the stubby lambda as an argument:
has_many :locations, -> { joins(:locations).uniq }
Also you can define own AR relation method, it stil use a simple has_many macro.
has_many :locations do
def only_uniq
joins(:locations).uniq
end
end
Now use it:
c = City.find(123)
c.locations.only_uniq
It does the same thing as scope or lambda in has_many.

In Rails 4 how do I write code that will retrieve objects instead of active record relations?

I have this code:
Sectionheader.where(:doc_id => #doc_id)
which returns:
#<ActiveRecord::Relation
[#<Sectionheader id: 1, section_id: nil, content: "a15+,f15+,a15+,f15+,a15+,f15+,a15+,f15+", created_at: "2014-08-13 18:18:39", updated_at: "2014-08-13 18:18:39", documentname: nil, doc_id: 1, row_number: 3, mergedsectionheader_id: nil>,
#<Sectionheader id: 2, section_id: nil, content: "A50+,F50+,A50+,F50+,A50+,F50+,A50+,F50+", created_at: "2014-08-13 18:18:39", updated_at: "2014-08-13 18:18:39", documentname: nil, doc_id: 1, row_number: 12, mergedsectionheader_id: nil>,
This result set is an array of activerecord relation objects. How can I instead get objects of type Sectionheader?
There used to be this method but it seems its been deprecated in rails 4
example this will return an array of person objects.
Person.find(1, :conditions => "administrator = 1", :order => "created_on DESC")
http://apidock.com/rails/ActiveRecord/Base/find/class
As Sergio Tulentsev commented above.
If you want to get an array of Sectionheader records from a relation, you can call #to_a
Sectionheader.where(:doc_id => #doc_id).to_a
If you wanted to eager-load the relation, you can call #load
Sectionheader.where(:doc_id => #doc_id).load
If you wanted to skip AR model instantiation completely, you could call #pluck(col1, col2, ...). This will return a multi-dimentional array representing the records.
Sectionheader.where(:doc_id => #doc_id).pluck(:id, :section_id, :content)
What you actually have is a relation object representing your result set. If you were to perform an operation on it which required actual data from the database, it would resolve into an array style object. You can see this in action in the response, where the console is showing you actual data.
#<ActiveRecord::Relation
[#<Sectionheader id: 1, section_id: nil, content: "a15+,f15+,a15+,f15+,a15+,f15+,a15+,f15+", created_at: "2014-08-13 18:18:39", updated_at: "2014-08-13 18:18:39", documentname: nil, doc_id: 1, row_number: 3, mergedsectionheader_id: nil>,
#<Sectionheader id: 2, section_id: nil, content: "A50+,F50+,A50+,F50+,A50+,F50+,A50+,F50+", created_at: "2014-08-13 18:18:39", updated_at: "2014-08-13 18:18:39", documentname: nil, doc_id: 1, row_number: 12, mergedsectionheader_id: nil>, ...
What this actually means is that #<ActiveRecord::Relation is the container. [ shows that an array type object has been opened. #<Sectionheader id: 1, ... is the first element of the array, and so on.
If you hadn't ended your statement there (dumping it to the console and forcing ActiveRecord to make the query) you would have a relation object representing the SQL of your query. You could add to this (with a select, or conditions or ordering etc.) if you wished without incurring the penalty of further database look-ups.
For most situations you can (and probably should) just treat this as an array. You can do a .to_a on the relation if your normal array methods aren't working, or .attributes on a single object to get a hash of the values returned by the query.
For example, you could do:
Sectionheader.where(:doc_id => #doc_id).each do |sectionheader|
puts sectionheader.doc_id
end
quite happily.

What does it mean when a instance method returns a scope and how to access them?

I'm using Closure_Tree gem and one of its instance methods, tag.descendants, returns a scope of all children, children's' children.
**tag.descendants** returns a scope of all children, childrens' children, etc., excluding self ordered by depth.
My questions are:
What is scope? Is it different from the name_scope?
It seems like the tag.descendants method is returning a hash. Please correct me if I'm wrong. And how can I access and return the name values?
This is what I received from rails console:
2.0.0-p353 :010 > #tag.descendants
Tag Load (0.5ms) SELECT "tags".* FROM "tags" INNER JOIN "tag_hierarchies" ON "tags"."id" = "tag_hierarchies"."descendant_id" WHERE "tag_hierarchies"."ancestor_id" = ? AND ("tags"."id" != 1) ORDER BY "tag_hierarchies".generations asc [["ancestor_id", 1]]
=> #<ActiveRecord::AssociationRelation [#<Tag id: 4, name: "Drinks", created_at: "2014-01-25 09:53:20", updated_at: "2014-01-25 09:53:20", parent_id: 1>, #<Tag id: 5, name: "Alcoholic", created_at: "2014-01-25 16:12:43", updated_at: "2014-01-25 16:12:43", parent_id: 4>, #<Tag id: 6, name: "Non-Alcoholic", created_at: "2014-01-25 16:14:13", updated_at: "2014-01-25 16:14:13", parent_id: 4>]>
2.0.0-p353 :011 >
I would like to know how I could call the name values of all the descendants. I've tried #tag.descendants.name but it returned "tag".
2.0.0-p353 :011 > #tag.descendants.name
=> "Tag"
Scopes are what allow you to take one big Active Record object and split it up into small different parts. For example you can scope projects so that user A can only see project A and user B can only see Project B, while all projects are on the project table. Check out the api it may clear things up about how you set a scope http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope
#tag.descendants.pluck(:name)
the reason #tag.descendants.name doesn't work is because you are calling the name method on a collection of decendants and it doesn't know which name to give you.

Rails, Mongoid: use custom key and custom key format

I have model Account:
class Account
include Mongoid::Document
include Mongoid::Timestamps
...
end
I want to use specific ids with specific format. I want id to be 16-digits instead of 4ceede9b5e6f991aef000007, something like that: 1111222233334444.
What is the best practice to do it?
If the id is a simple number, try:
class Account
include Mongoid::Document
include Mongoid::Timestamps
identity :type => Integer
end
account = Account.new :id => 1111222233334444
#=> #<Account _id: 1111222233334444, created_at: nil, updated_at: nil>
account.save
#=> true
account
#=> #<Account _id: 1111222233334444, created_at: 2010-11-26 00:48:27 UTC, updated_at: 2010-11-26 00:48:27 UTC>
Account.count
#=> 1
Account.first
#=> #<Account _id: 1111222233334444, created_at: 2010-11-26 00:48:27 UTC, updated_at: 2010-11-26 00:48:27 UTC>
If you want to use letters in the id too, you can do identity :type => String instead.

Resources