Search code examples
ruby-on-railsdeviseruby-on-rails-4

Devise as a nested resource - Routes


I am working on a fairly simple app. The basics of which are that I have 2 models, one for departments (department.rb below) and one for users (user.rb below). Departments have many users and users belong to departments.

I am using Devise (3.0.0.rc & Rails 4.0.0.rc1) for the user authentication and have done a migration to add department_id to the user model as the foreign key.

I am having a problem with getting routes that will seem logical to the users, who will go to their departments homepage and have the option to sign up or sign in from that page. Something like www.example.com/departments/department:id/sign_in

Without Devise being involved I think I could achieve this with a simple nested resource in my routes.rb. Something like:

resources :departments do
  resources :users
end

Using Devise I have tried:

resources :departments do
  devise_for :users, :path => ''
end

This creates a lot of routing errors so I think I must be heading down the wrong path and that there is probably an easier way. Being fairly new to rails I was hoping someone could point me in the right direction to a better solution.

My user.rb model:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  belongs_to :department

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  validates :department_id, presence: true
end

My department.rb model is:

class Department < ActiveRecord::Base
  has_many :users

.... All my validation rules
end

Solution

  • I tried to replicate your app and for me this worked. Try to play with devise_scope...

    #routes.rb    
    
    resources :departments
    
    devise_for :users
    
    devise_scope :user do
      get 'departments/:department_id/sign_in' => 'devise/sessions#new', :as => :department_user_sign_in
    end