combine 2 objects and sort rails 5

后端 未结 2 1020
南旧
南旧 2020-12-20 05:49

I want to show a time link mixing comments and post so I have this objects

@posts = Post::all()
@comments = Comment::all()

If I do this

相关标签:
2条回答
  • 2020-12-20 06:04

    Posts and comments are different models (and different tables), so we can't write SQL to get sorted collection, with pagination etc.

    Usually I use next approach when I need mixed timeline.

    I have TimelineItem model with source_id, source_type and timeline_at fields.

    class TimelineItem < ApplicationRecord
      belongs_to :source, polymorphic: true
    end
    

    Then I add in models logic to create timeline_item instance when needed:

    has_many :timeline_items, as: :source
    after_create :add_to_timeline
    
    def add_to_timeline
      timeline_items.create timeline_at: created_at
    end
    

    Then search and output as simple as

    TimelineItem.includes(:source).order(:timeline_at).each { |t| pp t.source }
    
    0 讨论(0)
  • 2020-12-20 06:09

    Solution#1 You can achieve this using UNION query.

    sql= 'SELECT id, name, date FROM posts UNION ALL SELECT id, name, date FROM comments ORDER BY date'
    ActiveRecord::Base.connection.execute(sql)
    

    but union query will only work when you have same column names in both tables.

    Solution#2 Add ordering logic in your view.

    If you are simply displaying these records on html page then let them load on page without any specific order i.e.(first posts and then comments). Write javascript code to sort DOM elements which will run after page load.

    for ref: Jquery - sort DIV's by innerHTML of children

    Solution#3 Refactor your DB schema and put posts and comments in same database table. Then you will be able to query on single table. Something like this,

    class Text < ActiveRecord::Base
    end
    
    class Post < Text 
    end
    
    class Comment < Text
    end
    

    Query will be Text.order(:date)

    Refactoring your DB schema is too much to solve this problem. Do it if it makes sense for your application.

    0 讨论(0)
提交回复
热议问题