2
\$\begingroup\$

My method takes a long time to respond, so I'd like to make this method more efficient. I'd also like this method made with joins.

 def all_shows_with_videos
    @arr = []
    tvs = Tv.all
    tvs.each do |tv|
      tv_tmp = {:name => tv.name, :id => tv.id}
      tv_tmp[:videos] = tv.videos
      tv_tmp[:seasons] = []
      season_tmp = {}
      tv.seasons.each do |season|
        season_tmp = {:name => season.name, :id => season.id}
        season_tmp[:videos] = season.videos
        season_tmp[:episodes] = []
        season.episodes.each do |episode|
        season_tmp[:episodes] << {:name => episode.name, :id => episode.id} if episode.videos?
        end
        tv_tmp[:seasons].push(season_tmp) if !season_tmp[:videos].blank? or !season_tmp[:episodes].blank?
      end

      @arr.push(tv_tmp) if !tv_tmp[:videos].blank? or !tv_tmp[:seasons].blank?
    end

    @arr = Kaminari.paginate_array(@arr).page(params[:page]).per(5)
    respond_to do |format|

      format.json {render :json => @arr}
    end
  end

Output:

[
    {
        "name": "Iron Man",
        "id": 95,
        "videos": [
            {
                "id": 1,
                "name": "Trailer 1",
                "site": "Youtube.com",
                "link": "Google.com",
                "quality": null,
                "video_type": null,
                "videoable_id": 95,
                "videoable_type": "Tv",
                "created_at": "2014-05-26T07:05:39+05:00",
                "video_source": null,
                "video_source_cd": null
            }
        ],
        "seasons": []
    },
    {
        "name": "How I Met Your Mother",
        "id": 100,
        "videos": [
            {
                "id": 13,
                "name": "Trailer 1",
                "site": null,
                "link": "google.com",
                "quality": "1020",
                "video_type": "Trailer",
                "videoable_id": 100,
                "videoable_type": "Tv",
                "created_at": "2014-06-09T10:05:03+05:00",
                "video_source": null,
                "video_source_cd": null
            }
        ],
        "seasons": []
    },
    {
        "name": "my tv",
        "id": 124,
        "videos": [
            {
                "id": 59,
                "name": "Trailer 1",
                "site": null,
                "link": "google.com",
                "quality": "1020",
                "video_type": "Trailer",
                "videoable_id": 124,
                "videoable_type": "Tv",
                "created_at": "2014-06-20T06:59:32+05:00",
                "video_source": null,
                "video_source_cd": null
            }
        ],
        "seasons": []
    },
    {
        "name": "Game of Thrones",
        "id": 151,
        "videos": [
            {
                "id": 129,
                "name": "",
                "site": null,
                "link": null,
                "quality": null,
                "video_type": "Season",
                "videoable_id": 151,
                "videoable_type": "Tv",
                "created_at": "2014-09-02T11:13:40+05:00",
                "video_source": null,
                "video_source_cd": null
            },
            {
                "id": 130,
                "name": "",
                "site": null,
                "link": "",
                "quality": null,
                "video_type": null,
                "videoable_id": 151,
                "videoable_type": "Tv",
                "created_at": "2014-09-02T11:13:40+05:00",
                "video_source": null,
                "video_source_cd": null
            },
            {
                "id": 131,
                "name": "",
                "site": null,
                "link": "",
                "quality": null,
                "video_type": null,
                "videoable_id": 151,
                "videoable_type": "Tv",
                "created_at": "2014-09-02T11:13:40+05:00",
                "video_source": null,
                "video_source_cd": null
            }
        ],
        "seasons": []
    },
    {
        "name": "Under the Dome",
        "id": 160,
        "videos": [],
        "seasons": [
            {
                "name": "Season Specials",
                "id": 267,
                "videos": [],
                "episodes": [
                    {
                        "name": "Inside Chester's Mill",
                        "id": 1112
                    }
                ]
            }
        ]
    }
]
\$\endgroup\$
1
\$\begingroup\$

Some notes:

  • Move all logic to models.
  • or is used for control-flow, || for boolean operations.
  • season_tmp is initialized for no reason.
  • Don't resuse variables (@arr).
  • !collection.blank? -> collection.present?
  • Code is shorter and more declarative if you use functional expressions instead of imperative commands (each, push and so on).

I'd write:

class Tv
  def self.shows_with_videos
    Tv.all.map do |tv|
      seasons = tv.seasons.map do |season|
        episodes_with_videos = season.episodes.select(&:videos?)
        if season.videos.present? || episodes_with_videos.present?
          episodes = episodes_with_videos.map do |episode|
            {:name => episode.name, :id => episode.id}
          end
          {:name => season.name, :id => season.id, :videos => season.videos, :episodes => episodes}
        end
      end.compact

      if tv.videos.present? || seasons.present?
        {:name => tv.name, :id => tv.id, :videos => tv.videos, :seasons => seasons}
      end
    end.compact
  end
end

class TvsController
  def all_shows_with_videos
    @shows_paginated = Kaminari.paginate_array(Tv.shows_with_videos).page(params[:page]).per(5)

    respond_to do |format|
      format.json { render(:json => @shows_paginated) }
    end
  end
end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.