Search code examples
ruby-on-railsrubyroutesslug

Routing to show action instead of custom action


news_controller.rb

 class NewsController < ApplicationController
    before_action :set_news, only: [:show]
    before_action :authenticate_user!, except: [:show, :index ]
    def index

    @news = News.where( state: true ).paginate(:page => params[:page],  :per_page => 12).order('id DESC')

    end

    def new

      @news = News.new


    end

     def show
     @news_photos = @news.news_photos
     end


      def create
        @news = News.new(news_params)
        if @news.save
          if params[:images]
            params[:images].each do |image|
              @news.news_photos.create(image: image)
            end
          end

          @news_photos = @news.news_photos
          redirect_to edit_news_path(@news), notice: "Saved..."
        else
          render :new
        end
      end

      def destroy
        @news = News.find(params[:id])
        @news.destroy

        respond_to do |format|
          format.html { redirect_to news_index_path }
         # format.json { head :no_content }
       end
     end

     def search
        @news = News.search(params[:search])
    end



    private
      def set_news
        @news = News.find(params[:id])
      end 

    def news_params
        params.require(:news).permit( :title, :description, :category, :keywords, :user_id, :email, :user_name)
    end
    end

news.rb

     class News < ApplicationRecord
     extend FriendlyId
       friendly_id :slug_candidates, use: [:slugged, :finders, :history]

         def slug_candidates 
         [ :title,
         [:title, :id]
          ] 
         end
        def self.search(search)
        pg_search_scope :search_full_text, 
                :against => :full_text, 
                :using => { :tsearch => { :prefix => true  }  }
                end 
             end

index.html.erb

        <div class="fh5co-box">
            <h3 class="heading">Search</h3>
            <%= form_tag(look_path, :method => "get") do %>
           <%= text_field_tag :search, params[:search], placeholder: "Search news" %>
            <%= submit_tag "Search" %>
             <% end %>
        </div>
    </div>
</div>

routes.rb

      resources :news, :except => [ :search]
      get 'news/search'  => 'news#search', :as => 'look'

As I submit the data inside the search field, it is routing to the show action instead of search action.

the routes are

 ews_index GET      /news(.:format)                              news#index
                                  POST     /news(.:format)                              news#create
                         new_news GET      /news/new(.:format)                          news#new
                        edit_news GET      /news/:id/edit(.:format)                     news#edit
                             news GET      /news/:id(.:format)                          news#show
                                  PATCH    /news/:id(.:format)                          news#update
                                  PUT      /news/:id(.:format)                          news#update
                                  DELETE   /news/:id(.:format)                          news#destroy
                             look GET      /news/search(.:format)                       news#search

log:

     Started GET "/news/search?utf8=%E2%9C%93&search=tax&commit=Search" for 183.83.117.57 at 2017-04-10 07:36:13 -0500
        Processing by NewsController#show as HTML
          Parameters: {"utf8"=>"▒~\~S", "search"=>"tax", "commit"=>"Search", "id"=>"search"}
          ^[[1m^[[36mNews Load (0.5ms)^[[0m  ^[[1m^[[34mSELECT  "news".* FROM "news" WHERE "news"."slug" = $1 ORDER BY "news"."id" ASC LIMIT $2^[[0m  [["slug", "search"], ["LIMIT", 1]]
          ^[[1m^[[36mNews Load (0.7ms)^[[0m  ^[[1m^[[34mSELECT  "news".* FROM "news" INNER JOIN "friendly_id_slugs" ON "friendly_id_slugs"."sluggable_id" = "news"."id" AND "friendly_id_slugs"."sluggable_type" = $1 WHERE ("friendly_id_slugs"."sluggable_type" = 'News' AND "friendly_id_slugs"."slug" = 'search') ORDER BY "friendly_id_slugs"."id" DESC LIMIT $2^[[0m  [["sluggable_type", "News"], ["LIMIT", 1]]
        Completed 404 Not Found in 5ms (ActiveRecord: 1.2ms)



        ActiveRecord::RecordNotFound (can't find record with friendly id: "search"):

        app/controllers/news_controller.rb:111:in `set_news'

Don't know where I have gone wrong.Is there anything to do with the slugs???

Any Help is highly Appreciated.Thanks in Advance!!!


Solution

  • Routes are search for in order.

    So in other words you show action matches the get request for /news/(:id) and your system processes SHOW. Move the line:

      get 'news/search'  => 'news#search', :as => 'look'
    

    higher up in the routes file and it should work fine, keep in mind though that this will block search from being used as a id/slug. A cleaner route would be

      get '/search/news'  => 'news#search', :as => 'look'
    

    as it'd get outside the news scope and you wouldn't have conflicts with the news model.