ruby on rails - 路由从 3.x 到 4.x 的错误移植

ruby on rails - routes error porting from 3.x to 4.x

我已经开始将我的一个应用程序从 rails 3.x 移植到 rails 4.x...

当我在开发中启动应用程序时,我收到一个与路由定义相关的错误:

=> Booting WEBrick
=> Rails 4.2.5 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
/home/francesco/.rvm/gems/ruby-2.2.2@Best-i-gest_v2/gems/actionpack-4.2.5/lib/action_dispatch/routing/route_set.rb:549:in `add_route': Invalid route name, already in use: 'app_settings'  (ArgumentError)
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here: 
http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
.....

这里是我的 routes.rb 文件的一部分,其中包含标记为双重定义的路由:

.....
get 'app_settings' => 'admin/app_settings#index', :as => 'app_settings'
put 'app_settings' => 'admin/app_settings#index', :as => 'app_settings'
post 'app_settings' => 'admin/app_settings#index', :as => 'app_settings'
post 'app_settings/upload' => 'admin/app_settings#upload_logo', :as => 'app_settings/upload'
.....

我已经定义了这些路由,因为我将仅使用 'index' 操作来管理与应用程序设置相关的所有操作(应用程序有一个存储所有设置的数据库记录,该记录是自动创建的第一次用户将加载页面,然后在保存时更新)正如你在这里看到的:

# only one record here! it will store all the application settings
def index
  # manages all the controller actions inside the index...
  if request.get?
    # this is a get request... returns the first settings record or a new one if none exists!
    @app_settings = !AppSettings.all.first.nil? ? AppSettings.all.first : AppSettings.new
  elsif request.post?
    # this is a post request, the settings record will be created
    @app_settings = AppSettings.new(params[:app_settings])
    @app_settings.save
  elsif request.put?
    # this will update the existing app_settings record
    @app_settings = AppSettings.find_by_id(params[:app_settings][:id].to_i)
    @app_settings.update_attributes(params[:app_settings])
  end

  # renders the index page
  render "index"
end

我正在寻找更正 routes.rb 文件的方法(保持我的控制器和视图不变!!)或解决此问题的替代方法!!

等待您的建议, 非常感谢您的宝贵时间,

弗朗切斯科

好像你在一个方法中有太多的逻辑。我相当确定即使在 rails 3 中也是不可接受的。

使用休息路线怎么样(rails routing guide 中描述的资源)

resources :app_settings, only: [:index, :update, :create]

这将为索引(geT)、更新(补丁)、创建(post)创建三个路由。

您的控制器现在看起来像这样:

def index
  @app_settings = !AppSettings.all.first.nil? ? AppSettings.all.first : AppSettings.new
end 

def create
  @app_settings = AppSettings.new(params[:app_settings])
  @app_settings.save
end

def update
  @app_settings = AppSettings.find_by_id(params[:app_settings][:id].to_i)
  @app_settings.update_attributes(params[:app_settings])
end

也不需要使用render 'index' ... rails会自动寻找/app/app_settings/index.html.erb

好的伙计们, 我解决了... 非常感谢 Alexandre 和 Ryan 指导我解决了这个问题.....

嗯, 亚历山大确定你是对的!单个动作中的逻辑太多,所以... 这是我的文件的新版本:

routes.rb:

....
post 'app_settings/upload' => 'admin/app_settings#upload_logo', :as => 'app_settings/upload'

# site admin area
namespace :admin do
  resources :app_settings, only: [:index, :update, :create]
  resources :users
  ......

end
.....

如您所见,我在管理命名空间中插入了 app_settings 路由 ..

app_settings_controller.rb:

# app_settings security settings - used for declarative authorization
filter_access_to [:index, :create, :update], :require => :manage
filter_access_to :upload_logo, :require => :manage

# app_settings index method (this replaces the show method so all actions will be managed in the index view page)
def index
  # this is a get request... returns the first settings record or a new one if none exists!
  @app_settings = !AppSettings.first.nil? ? AppSettings.first : AppSettings.new(id: 1)
  @app_settings.save
end 

# app_settings create method
def create
  # this is a post request, the settings record will be created
  @app_settings = AppSettings.new(app_settings_params)
  @app_settings.save
  # renders the index page
  render "index"
end

# app_settings update method
def update
  # this will update the existing app_settings record
  @app_settings = AppSettings.find_by_id(params[:app_settings][:id].to_i)
  @app_settings.update_attributes(app_settings_params)
  # renders the index page
  render "index"
end
......

如您所见,我已经实施了您的解决方案,将索引视图保留为应用程序使用的唯一视图,只是为了在应用程序内部不做太多更改.... 我已经根据您建议的修改相应地修复了 declarative_authorization 部分,并按照 Ryan 的建议简化了新记录的创建,但添加了一些额外的内容(我已经指定了记录 ID,然后保存了记录本身)在我看来,所有这些都是为了防止 form_for 声明如下的另一个问题:

<!-- application settings edit form -->
<%= form_for [:admin, @app_settings] do |app_sett| %>
.....

.....
<% end %>

再次感谢大家!!

希望在每次阅读本网站的页面时都能继续向您学习!!

问候,

弗朗切斯科