RailsApps / rails_apps_composer

A gem with recipes to create Rails application templates for Rails starter apps.
http://railsapps.github.io/rails_apps_composer/
1.42k stars 306 forks source link

`roles` recipe fails if Pundit is enabled but no authentication is chosen #310

Closed roryokane closed 10 years ago

roryokane commented 10 years ago

When I try to generate an app with the following preferences and recipes (just the core collection), the app generation stops in the middle due to the following “No such file or directory” error for the file app/models/user.rb:

RECIPES
["core", "deployment", "devise", "email", "extras", "frontend", "gems", "git", "init", "learn_rails", "locale", "omniauth", "pages", "rails_bootstrap", "rails_devise", "rails_devise_pundit", "rails_foundation", "rails_mailinglist_signup", "rails_omniauth", "rails_signup_download", "railsapps", "readme", "roles", "setup", "tests"]
PREFERENCES
{:git=>true, :apps4=>"none", :dev_webserver=>"thin", :prod_webserver=>"thin", :database=>"sqlite", :templates=>"slim", :tests=>"rspec", :continuous_testing=>"none", :frontend=>"none", :email=>"none", :authentication=>"none", :authorization=>"pundit", :form_builder=>"none", :pages=>"none"}
       roles  recipe stage two
    generate    migration AddRoleToUsers role:integer
      invoke  active_record
      create    db/migrate/20140704205248_add_role_to_users.rb
      insert    app/models/user.rb
The template [/var/folders/2p/rwsf147j61j4xcfxwdl13g9w0000gn/T/template20140704-55936-1szjf4d] could not be loaded. Error: No such file or directory @ rb_sysopen - /Users/[…]/app/models/user.rb

From inspecting recipes/roles.rb, I believe this is the combination of preferences that causes the error: :authentication=>"none", :authorization=>"pundit". The roles recipe assumes that app/models/user.rb was already created by an authentication plugin, but in my case, it was not.

I selected that I preferred no authentication because I wanted to manually install an authentication plugin not in the list, AuthLogic, after rails_apps_composer generated my app. And I wanted to use Pundit for authorization because I expected to manage roles in my app.

I think you can fix this by changing line 6 of roles.rb. The line should check not only that prefs[:authorization] is 'pundit', but also that prefs[:authentication] is not equal to 'none'.

DanielKehoe commented 10 years ago

Thanks for reporting this issue. I will handle it by generating a User model if Devise or OmniAuth are not selected for authentication. Will this work for you?

# recipes/roles.rb
stage_two do
  say_wizard "recipe stage two"
  if prefer :authorization, 'pundit'
    if prefer :authentication, 'none'
      generate 'model User email:string'
      run 'bundle exec rake db:migrate'
    end
    generate 'migration AddRoleToUsers role:integer'
    role_boilerplate = "  enum role: [:user, :vip, :admin]\n  after_initialize :set_default_role, :if => :new_record?\n\n"
    role_boilerplate << "  def set_default_role\n    self.role ||= :user\n  end\n\n" if prefer :authentication, 'devise'
    if prefer :authentication, 'omniauth'
      role_boilerplate << <<-RUBY
  def set_default_role
    if User.count == 0
      self.role ||= :admin
    else
      self.role ||= :user
    end
  end
RUBY
    end
    inject_into_class 'app/models/user.rb', 'User', role_boilerplate
  end
  ### GIT ###
  git :add => '-A' if prefer :git, true
  git :commit => '-qm "rails_apps_composer: add roles to a User model"' if prefer :git, true
end

This will create a User model so we can inject the code needed to implement roles.