rubyruby-on-rails-4actioncontroller

How to display specific posts?? Actioncontroller Ruby on Rails


I'm trying to make Podcast pages. On the index page, I want to display the latest podcast at the top, next three podcasts in the middle, and rest of all at the bottom of the page

For example, I have 25 episodes and want to display like below

25 at the top

22, 23, 24 in the middle

21,20,19,18 ~ 1 at the bottom

My controller

class PodcastsController < ApplicationController
  before_action :find_podcast, only: [:show, :edit, :update, :destroy]

  # GET /podcasts
  # GET /podcasts.json

  def index
    @podcasts = Podcast.order("created_at DESC").limit(1)

  end



  # GET /podcasts/1
  # GET /podcasts/1.json
  def show
    @podcasts = Podcast.all
  end

  # GET /podcasts/new
  def new
    @podcast = Podcast.new
  end

  # GET /podcasts/1/edit
  def edit
  end

  # POST /podcasts
  # POST /podcasts.json
  def create
    @podcast = Podcast.new(podcast_params)

    respond_to do |format|
      if @podcast.save
        format.html { redirect_to @podcast, notice: 'Podcast was successfully created.' }
        format.json { render :show, status: :created, location: @podcast }
      else
        format.html { render :new }
        format.json { render json: @podcast.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /podcasts/1
  # PATCH/PUT /podcasts/1.json
  def update
    respond_to do |format|
      if @podcast.update(podcast_params)
        format.html { redirect_to @podcast, notice: 'Podcast was successfully updated.' }
        format.json { render :show, status: :ok, location: @podcast }
      else
        format.html { render :edit }
        format.json { render json: @podcast.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /podcasts/1
  # DELETE /podcasts/1.json
  def destroy
    @podcast.destroy
    respond_to do |format|
      format.html { redirect_to podcasts_url, notice: "#{@pocast.title} was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def find_podcast
      @podcast = Podcast.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def podcast_params
      params.require(:podcast).permit(:episode_url, :episode_title, :episode_description, :episode_audio_url, :episode_number)
    end
end

index.html.haml

%section.no-spacing
  .row   
    .columns.large-12
      - @podcasts.each do |podcast|
         %h3
           = podcast.episode_number
           = podcast.episode_audio_url
           = podcast.episode_description

So far, I could display the latest one but stuck at showing three(2nd, 3rd, 4th) and rest of the pages (5th ~ all) in descending order.

Appreciates your help in advance.


Solution

  • I would try something like this.
    First of all, it would be great to make a clean controller and a query object to work with the podcast list logic.

    class PodcastsController < ApplicationController
    
      def index
        podcast_query = PodcastQuery.new
        # this is one podcast object
        @most_recent_podcast = podcast_query.most_recent
        # these are arrays of podcasts
        @next_three_most_recent_podcasts = podcast_query.next_three_most_recent
        @remaining_podcasts = podcast_query.remaining
      end
    end
    
    # app/models/podcast_query.rb
    class PodcastQuery
      def initialize
        @podcasts = Podcast.order("created_at DESC")
      end
    
      def most_recent
        @podcasts[0] || (raise StandardError.new "you need at least one Podcast")
      end
    
      def next_three_most_recent
        @podcasts[1..3] || []
      end
    
      def remaining
        @podcasts[4..-1] || []
      end
    end