Bitwise
Bitwise

Reputation: 8461

Understanding rails routes

I getting very confused about how rails routing works. I have a very simple app at this point so should be easy to debug. Here is my problem - I have a controller that is trying to call a show action, but it seems to be overriding another action that I'm calling in the same controller. As far as I can tell from rake routes is that if the url read this localhost.com/subscribers/1 that should render the id of the subscriber that I'd like to view but I also have a url that get called like this localhost.com/subscribers/visit so effectively none of these page work now? I really don't know what's happening here so any help would be great! Here is my code.

CONTROLLER

   class SubscribersController < ApplicationController
  helper_method :sort_column, :sort_direction

  def index
    @search = Subscriber.search(params[:q])
    @subscriber = @search.result
    @search.build_condition if @search.conditions.empty?
    @search.build_sort if @search.sorts.empty?
  end

  def show
    @subscriber = Subscriber.find_by(id: params[:id])
  end

  def new
    @subscriber = Subscriber.new
  end

  def create
    @subscriber = Subscriber.new(subscriber_params)
    if @subscriber.save
      @subscriber.touch(:subscription_date)
      SubscriberMailer.welcome_subscriber(@subscriber).deliver_now
      flash[:notice] = "Subscriber Has Been Successfully Created"
      redirect_to new_subscriber_path(:subscriber)
    else
      render "new"
    end
  end

  def search
    @subscriber = Subscriber.new
  end

  def visit
    @subscriber = Subscriber.find_by_phone_number(params[:phone_number])
    if @subscriber
      @subscriber.visit ||= 0
      @subscriber.visit += 1
      @subscriber.save
      render "visit"
    end
  end

ROUTES:

    devise_for :users
  resources :subscribers 
  resources :comments, only: [:new, :create]

  get "subscribers/search", to: "subscribers#search"
  get "subscribers/visit", to: "subscribers#visit"

  root "subscribers#new"

RAKE ROUTES:

subscribers GET    /subscribers(.:format)             subscribers#index
                   POST   /subscribers(.:format)             subscribers#create

    new_subscriber GET    /subscribers/new(.:format)         subscribers#new
   edit_subscriber GET    /subscribers/:id/edit(.:format)    subscribers#edit
        subscriber GET    /subscribers/:id(.:format)         subscribers#show
                   PATCH  /subscribers/:id(.:format)         subscribers#update
                   PUT    /subscribers/:id(.:format)         subscribers#update
                   DELETE /subscribers/:id(.:format)         subscribers#destroy
          comments POST   /comments(.:format)                comments#create
       new_comment GET    /comments/new(.:format)            comments#new
subscribers_search GET    /subscribers/search(.:format)      subscribers#search
 subscribers_visit GET    /subscribers/visit(.:format)       subscribers#visit

Am I doing something fundamentally wrong here? Please help me out!

Upvotes: 3

Views: 77

Answers (1)

Nils Landt
Nils Landt

Reputation: 3134

The router tries to match the routes going from the top of routes.rb to the bottom, and uses the first route that matches.

In your case, /subscribers/visit matches /subscribers/:id - the router thinks it's the show action for a subscriber with the ID visit.

If you move your custom paths above your resources :subscribers in the routes file, you'll achieve the behaviour you're expecting.

Upvotes: 4

Related Questions