Combine 2 Objects and Sort Rails 5

Combine two ActiveRecord results and sort by a shared joined table attribute

You can try the following:

(@convos + @group_meetings).sort_by { |item| item.msgs.minimum(:created_at) }

Combine active_record models and sort by shared properties

The issue is that nil is only comparable with nil:

       nil <=> nil  # => 0         # -1, 0, 1 are good
"priority" <=> nil # => nil # `nil` means not comparable
# and you get an error from `sort_by`

Solution is to avoid comparing nil with anything else or explicitly handle the comparison.

You can use sort and sort the nils yourself:

ary = (Author.all + Photographer.all)

ary.sort do |a, b|
if a.priority && b.priority # priority <=> priority
a.priority <=> b.priority
elsif a.priority # priority <=> nil
-1 # nil is lower
elsif b.priority # nil <=> priority
1 # priority is higher
else # nil <=> nil
a.name <=> b.name # break the tie
end
end

You can split array in two, with priority and without priority, and sort each one. That way priority is compared to priority; nil is compared to nil, which is 0, and it falls back to comparing name (like the sort above, but elsif's never match):

ary.partition(&:priority).flat_map do |part|
part.sort_by { |i| [i.priority, i.name] }
end

Or a dumber way of doing this (it's also faster) is to make nil be something last:

ary.sort_by { |i| [i.priority||"zzz", i.name] }

Combine two ActiveRecord::Relation objects

If you want to combine using AND (intersection), use merge:

first_name_relation.merge(last_name_relation)

If you want to combine using OR (union), use or:

first_name_relation.or(last_name_relation)

Only in ActiveRecord 5+; for 4.2 install the where-or backport.

Combining two different ActiveRecord collections into one

Well, assuming that the result of querying both Hire and Deal models is an array of objects (collection), then you just use + to concatenate them into a new array and sort items by date with sort_by:

combined = ( Hire.all + Deal.all ).sort_by(&:date)

or use concat to concatenate one collection with another:

combined = Hire.all.concat( Deal.all ).sort_by(&:date)

Combine Two Database Columns to Order Data

For MySQL:

User.order('CONCAT(`first_name`, `last_name`)')

How to merge multiple objects from different models into one object in Rails?

You can create a PORO (plain old ruby object) to represent the combined object so something like:

class Stream 
attr_accessor :product, :post, :member, :selection

def initialize(attrs)
assign_attributes(attrs)
end
end

Then just initialize and create as many stream objects as you need using Stream.new(attrs). You can create an array of stream objects and loop through them to render or show multiple stream data.

For sorting an array of objects by its attributes you can use

objects.sort_by {|obj| obj.attribute}

Can I merge two Set objects in Ruby?

Why This Question is Useful

While the OP has been criticized for lack of research effort, it should be pointed out that the Ruby documentation for Set#merge is not friendly for new Rubyists. As of Ruby 2.3.0, it says:

Merges the elements of the given enumerable object to the set and returns self.

It offers merge(enum) as the signature, but no useful examples. If you need to know what classes mix in Enumerable, it can be difficult to grok from just this one piece of documentation what kind of duck-typed ducks can be merged in. For example, set.merge {foo: 'bar'}.to_enum will raise SyntaxError despite the fact that it is enumerable:

{foo: 'bar'}.to_enum.class
#=> Enumerator

{foo: 'bar'}.to_enum.class.include? Enumerable
#=> true

Merging Sets

If you're thinking of Set#merge as creating a set union, then yes: you can merge sets. Consider the following:

require 'set'

set1 = Set.new [1, 2, 3]
#=> #<Set: {1, 2, 3}>

set2 = Set.new [3, 4, 5]
#=> #<Set: {3, 4, 5}>

set1.merge set2
#=> #<Set: {1, 2, 3, 4, 5}>

Merging Other Enumerable Objects Like Arrays

However, you can also merge other Enumerable objects (like arrays) into a set. For example:

set = Set.new [1, 2, 3]
#=> #<Set: {1, 2, 3}>

set.merge [3, 4, 5]
#=> #<Set: {1, 2, 3, 4, 5}>

Using Array Union Instead

Of course, you may not need sets at all. Compare and contrast Set to array unions (Array#|). If you don't need the actual features of the Set class, you can often do similar things directly with arrays. For example:

([1, 2, 3, 4] | [3, 4, 5, 6]).uniq
#=> [1, 2, 3, 4, 5, 6]


Related Topics



Leave a reply



Submit