0

I am trying to sort data in my chatbox with data from two tables (kind of trying to make an events log place).

This is my chatbox:

Chatbox/Events Log

I want to sort the blue and green boxes based on date/time. Here's the code that I want to sort:

Code

Can you guide me on how to achieve this?

EDIT Updated Code:

Updated Code 3rd April Image

stats.html.erb file

<%
    @objects = (@solrs + @messages).sort_by &:created_at
%>

<% @objects.each do |obj| %>
  <% if obj.is_a? Solr %>
    <!-- Solrs Partial -->
    <%= render 'messages/solr' %>
  <% else %>
   <!-- Messages Partial -->
  <%= render @messages %>
  <% end %>
<% end %>  

Code Inside Solrs Partial

<% @solrs.each do |solr| %>

    <div class="row msg_container base_receive">  
        <div class="col-xs-10 col-md-10">
            <div class="messages msg_receive">
                <p class="">

                    Disease <b><%= solr.disease %></b> has been created with synonyms <b> <%= solr.synonym %></b> by <b><%= solr.user.first_name %> <%= solr.user.last_name %></b><br>

                </p>

                    <time> <%= solr.created_at.strftime("%d %b %4Y")%> • <%=solr.created_at.strftime("%I:%M%p")%></time>

            </div>
        </div>
    </div>

<% end %>  

Code Inside Messages Partial

<div class="row msg_container base_sent">
        <div class="col-md-1 col-xs-1">
        <p><em><%= message.user.first_name %>: </em></p>
    </div>

    <div class="col-md-10 col-xs-10">
        <div class="messages msg_sent">
            <p>
                <%= message.body %>
            </p>
            <time> <%= message.created_at.strftime("%d %b %4Y")%> • <%=message.created_at.strftime("%I:%M%p")%></time>
        </div>

    </div>
</div>

solr_controller file

def stats
        @messages = Message.custom_display
        @message = Message.new
        @solrs = Solr.all
        @users = User.all 
 end
Usman Ijaz
  • 13
  • 1
  • 5

1 Answers1

0

To sort multiple models together, first create a collection of the two:

@objects = @solrs + @messages

then, use [sort_by](https://apidock.com/ruby/Enumerable/sort_by):

@objects.sort_by &:created_at -or- @objects.sort_by { |obj| obj.created_at }

Pretty sure you can wrap that in to one line like:

@objects = (@solrs + @messages).sort_by &:created_at

[is_a?](https://apidock.com/ruby/Object/is_a%3F) will let you treat each one individually, this SO question goes over this nicely

Example:

solr_controller.rb

def stats
  @messages = Message.includes(:user).custom_display
     @solrs = Solr.includes(:user).all
   @objects = (@solrs + @messages).sort_by &:created_at
end

[.includes](https://apidock.com/rails/ActiveRecord/QueryMethods/includes) will let you access the associated user without querying the database again. Here's a good article on it.

assuming you're in /views/messages, adjust if your file structure is different

/messages/stats.html.erb

<% @objects.each do |obj| %>
  <% if obj.is_a? Solr %>
    <%= render partial: 'solr', locals: { solr: obj } %>
  <% else %>
    <%= render partial: 'message', locals: { message: obj } %>
  <% end %>
<% end %>

/messages/_solr.html.erb

<div class="row msg_container base_receive">  
  <div class="col-xs-10 col-md-10">
    <div class="messages msg_receive">
      <p>
        Disease <b> <%= solr.disease %> </b> 
        has been created with synonyms <b> <%= solr.synonym %> </b> 
        by <b> <%= solr.user.first_name %> <%= solr.user.last_name %> </b>
        <br>
      </p>
      <time>
        <%= solr.created_at.strftime("%d %b %4Y") %> • 
        <%= solr.created_at.strftime("%I:%M%p") %>
      </time>
    </div>
  </div>
</div>

/messages/_message.html.erb

<div class="row msg_container base_sent">
  <div class="col-md-1 col-xs-1">
    <p> <em> <%= message.user.first_name %>: </em> </p>
  </div>
  <div class="col-md-10 col-xs-10">
    <div class="messages msg_sent">
      <p> <%= message.body %> </p>
      <time> 
        <%= message.created_at.strftime("%d %b %4Y") %> • 
        <%= message.created_at.strftime("%I:%M%p") %>
      </time>
    </div>
  </div>
</div>
Community
  • 1
  • 1
  • Thanks. But would this not order only the messages model. So, in my case if you look at the code above I am trying to order messages and solr.. where both need to be ordered in correlation with each other based on timestamp. Also, what am i putting inside the where brackets - any column of the messages model? I am a newbie in rails... :) – Usman Ijaz Mar 30 '19 at 01:24
  • I'd probably just add them both to a collection `@objects_to_sort`, and then use [sort_by](https://apidock.com/ruby/Enumerable/sort_by) i.e: `@objects_to_sort.sort_by { |object| object.created_at}` use `-object.created_at` to reverse order – Richard Legacy Apr 01 '19 at 13:07
  • You've been a great help so far. Sorry, I am a little new to ruby on rails can you please take a look at the code image in the question and guide me on how to the collection in my views. As I am running ruby to show the elements from the two models (picture attached above). Thank you so much again, I hope you can take out some time to answer this query, this is driving me nuts! – Usman Ijaz Apr 02 '19 at 04:52
  • `@objects = @solrs + @messages` then `@objects.sort_by { |object| object.created_at }` or `@objects.sort_by &:created_at` – Richard Legacy Apr 02 '19 at 13:14
  • I've added this into my views... but how do I call this object to call columns in that model. For example, how do I call solr.disease (in my case)... I have added an image of the updated code under the edit heading in my original question... Sorry if this is a silly question but I am struggling so much to get this sorted... :( – Usman Ijaz Apr 02 '19 at 20:13
  • I would just test what the model of the object is, pretty sure you can use `kind_of?` [try this link](https://stackoverflow.com/questions/3893278/ruby-kind-of-vs-instance-of-vs-is-a) – Richard Legacy Apr 02 '19 at 23:22
  • Okay... something did happen but it's repeating all again an again. So what I understand is that it checks the first solr and message and compare them and order it according to which was created before but still include all the rest of them. To make it easier to read I have put my code in partials and added it under the edit in my code above plus the image of whats happening.... I think i am close to somewhere fixing it... Can you tell me why is it repeating and what do I need to change in my code above to fix this. THANKS A TON SO FAR!!! – Usman Ijaz Apr 03 '19 at 02:30
  • take out that `@solrs.each do`, we created a collection of ALL of BOTH objects, `sort by` sorts the whole collection, so you only need to iterate through it once (`@objects.each do`) you can do obj.disease in the solr portion or do: `<%= render partial: 'solr', locals: { solr: obj } %>` which casts the obj (which you just tested and know is of type solr) as 'solr' inside of the partial. You'd then use solr.disease inside of the partial instead of obj.disease, gonna edit my answer – Richard Legacy Apr 03 '19 at 12:41
  • THANK YOU SOOOO MUCH... This is working, I've probably spent over 30 hours on this problem :)))) (I am new to stackoverflow...how do I accept your answer as the solution?) – Usman Ijaz Apr 03 '19 at 13:30
  • Also something a little outside the question but if you guide me on the right track... If I use after_destroy method in my model.rb file... how do I call it in my views? :) – Usman Ijaz Apr 03 '19 at 13:41
  • No problem at all haha, looks like you accepted it perfectly :) I don't think you're really getting the seperation of model, view, controller. I'd look into it some more. Trying to jury-rig everything to work will just get you in more trouble down the road. If you can, I really recommend https://www.railstutorial.org/ (just hit the read button, it's free!) and if you're into books, 'The Rails 5 Way' by Obie Fernandez is invaluable. – Richard Legacy Apr 03 '19 at 17:31