问题
Try to build a welcome wizard and try to get existing rails code to be ported to be rails 4 compatible. Based mostly on previous great answer: https://stackoverflow.com/a/17255451/355281
I try to call http://books:3000/welcome/basics
This results in:
Circular dependency detected while autoloading constant WelcomeController
app/controllers/welcome_controller.rb
class Welcome::ApplicationController < ::ApplicationController
layout "welcome"
before_filter :authentice_user!
end
app/controllers/welcome_basics_controller.rb
class Welcome::BasicsControlller < Welcome::ApplicationController
before_action :authenticate_user!
before_filter :allowed?
def new
@step = Welcome::Basics.new(current_user)
end
def create
@step = Welcome::Basics.new(current_user)
if @step.save(params[:welcome_basics])
redirect_to welcome_some_other_step_path, :notice => "Yay"
else
render :new
end
end
private
def step
@step ||= Welcome::Basics.new(current_user)
end
helper_method :step
def allowed?
redirect_to previous_step_path unless step.allowed?
end
end
**app/models/welcome_basics.rb
class Welcome::Basics
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
def persisted?
false
end
def initialize(user)
@user = user
end
attr_reader :user
delegate :some_field, :some_other_field, :to => :user
validates_presence_of :some_field
def save(params)
user.some_field = params[:some_field]
user.some_other_field = params[:some_other_field]
if valid?
user.step = 2
user.save
end
end
def photo
@photo ||= Photo.new
end
def profile
@profile ||= user.profiles.first
end
end
/config/routes.rb
namespace :welcome do
resource :basics, :only => [:new, :create]
end
回答1:
I see a few things that appear to be off. The one that appears to be the biggest issue with Rails 4 vs Rails 3.2 is in your pseudo-model definition.
class Welcome::Basics
include ActiveModel::Model # Necessary for Rails 4
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
...
end
In your welcome_controller.rb
, you have authentice user
which should read authenticate user
.
In your welcome_basics_controller.rb
you misspelled controller in your definition, currently: Welcome::BasicsControlller
should be Welcome::BasicsController
.
I'd also recommend that you change your naming and inheritance to be a bit simpler and more inline with Rails convention over configuration. This would be my approach:
Since welcome_basics.rb is a pseudo-model, I'd put it in its own directory to prevent any potential automatic sourcing of ActiveModel. I'd also change the name to the singular to be in line with Rails conventions for models.
app/pseudo_models/welcome_basic.rb
class WelcomeBasic
include ActiveModel::Model # Necessary for Rails 4
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
...
end
Now I'd put your welcome_controller in a sub-directory called "welcome" within the controller directory:
app/controllers/welcome/welcome_controller.rb
class Welcome::WelcomeController < ApplicationController
layout "welcome"
before_filter :authenticate_user!
end
Then your basics controller should be called basics within the "welcome" directory, and since your inheriting from your welcome controller, you don't need to repeat the authenticate_user!
line. Also remember that you'll need to rename your calls to your pseudo-model from Welcome::Basics
to WelcomeBasic
. For Rails 4 you'll also need to implement strong params in your controller.
app/controllers/welcome/basics_controller.rb
class Welcome::BasicsController < Welcome::WelcomeController
before_filter :allowed?
def new
@step = WelcomeBasic.new(current_user)
end
def create
@step = WelcomeBasic.new(current_user)
if @step.save(basic_params) #updated to use strong_params
redirect_to welcome_some_other_step_path, :notice => "Yay"
else
render :new
end
end
private
#For strong_params
def basic_params
params.require(:welcome_basic).permit(:attribute1, :attribute2)
end
def step
@step ||= WelcomeBasic.new(current_user)
end
helper_method :step
def allowed?
redirect_to previous_step_path unless step.allowed?
end
end
/config/routes.rb
...
namespace :welcome do
resources :basics, :only => [:new, :create]
end
...
The other thing that you'll need to ensure is that your corresponding views are placed within the same directory structure as your controller, so you should have the following:
/app/views/welcome/basics/welcome.html.erb
One other note, when you say "I try to call http://books:3000/welcome/basics
", I assume you mean that your attempting to post your form? Otherwise, you should be calling http://books:3000/welcome/basics/new
in order to get your basics form. If you want that route to map to http://books:3000/welcome/basics
you'll need to make the corresponding adjustments in your config/routes.rb
file.
来源:https://stackoverflow.com/questions/18847103/rails-4-welcome-wizard-how-to-correct-this-code-to-make-it-work-for-rails-4