Making the controller clean and readable in (Ruby on Rails) I have this rails controller which works fine but a lot of business logic is confined in the controller which I believe is not a good practice.
class MoviesController &lt; ApplicationController
  before_action :set_movie, only: [ :edit, :update, :destroy ]
  rescue_from ActiveRecord::RecordNotFound, with: :render_404


  def index
    year = params[:year].split('-') unless params[:year].nil?
    starting_year = year[0] unless year.nil? || year.empty?
    ending_year = year[year.length - 1] unless year.nil? || year.empty?
    genre = params[:genre][0] unless params[:genre].nil?
    language = params[:language][0] unless params[:language].nil?
    quality = params[:quality][0] unless params[:quality].nil?
    rating = params[:rating_bound][0] unless params[:rating_bound].nil?
    order_by = params[:orders_filter][0] unless params[:orders_filter].nil?
    @movies = Movie.search_title(params[:title]).search_language(language).search_on_starting_year(starting_year).search_on_ending_year(ending_year).search_video_quality(quality).search_genre(
      genre
    ).search_rating(rating).order_on_filter(order_by).includes(:profile_photo)
  end


  def show
    @movie = Movie.includes(
      :profile_photo, :created_by, movie_roles: [:actor], feedback: [:user] 
    ).left_outer_joins(:likes, :ratings).select(
      'movies.*, CAST(AVG(ratings.value) AS DECIMAL(10,1)) AS rating, count(likes.likeable_id) * 6 as total_likes'
    ).find params[:id]
    @reviews = @movie.feedback.select { |item| item.type == 'Review' }
    @comments = @movie.feedback.select { |item| item.type == 'Comment' }
    @directors = @movie.movie_roles.select { |role| role.role_played == 'director' }
    @actors = @movie.movie_roles.select { |role| role.role_played == 'actor' }
  end

 
  def new
    @movie = Movie.new
    @movie.build_profile_photo
  end


  def edit
  end

  def render_404
    render file: &quot;#{Rails.root}/public/404&quot;, status: :not_found
  end

  # POST /movies
  # POST /movies.json
  def create
    parameters = movie_params
    @movie = Movie.new(parameters) 
    @movie.created_by = current_user

    if @movie.save
      redirect_to @movie, notice: 'Movie was successfully created.'
    else
      render :new, notice: 'Not Saved!'
    end
 end


  def update
    respond_to do |format|
      if @movie.update(movie_params)
        format.html { redirect_to @movie, notice: 'Movie was successfully updated.' }
        format.json { render :show, status: :ok, location: @movie }
      else
        format.html { render :edit }
        format.json { render json: @movie.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @movie.destroy
    respond_to do |format|
      format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

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

  # Only allow a list of trusted parameters through.
  def movie_params
    params.fetch(:movie, {}).permit(:name, :release_date, :video_quality, :synopsis, :genres, :language)
    params.fetch(:movie, {}).permit(:name, :release_date, :video_quality, :synopsis, :genres, :language, profile_photo_attributes: [:path])     
  end
end


I need to shrink the controller size and make the code look much clear and readable!
One thing you can do to simplify your controllers is use something like the scaffolding gem https://github.com/tubbo/controller_resources - that would reduce some of the boilerplate code.
For the #index method I would rewrite it chainging relations something like
  def index
    @movies = Movie.all.includes(:profile_photo)
    if params[:year].present?
      years = params[:year].split('-')
      @movies = @movies.search_on_ending_year(years.first)
      @movies = @movies.search_on_ending_year(years.last)
    end
    @movies = @movies.search_genre( params[:genre].first ) if params[:genre].present? 
    # etc
    @movies = @movies.order_on_filter(params[:orders_filter].filter) if params[:orders_filter].present?
  end

If you define your scopes something like
scope search_on_ending_year, -&gt;(year) { year ? some_condition : all }
then you can also remove the conditionals above
Note that you can combine that a simple way to check both nil? and empty? in one step is to use blank?. Likewise present? is very universal and checks that values are not nil, strings are not blank, arrays are not empty, etc
In the movie_params method
  def movie_params
    params.fetch(:movie, {}).permit(:name, :release_date, :video_quality, :synopsis, :genres, :language)
    params.fetch(:movie, {}).permit(:name, :release_date, :video_quality, :synopsis, :genres, :language, profile_photo_attributes: [:path])     
  end

the first line is both redundant and ignored
I think your code would also be simpler if you structured your html to avoid array parameters like this params[:orders_filter][0]