【问题标题】:ruby on rails - routes error porting from 3.x to 4.xruby on rails - 从 3.x 到 4.x 的路由错误移植
【发布时间】:2016-01-01 22:52:32
【问题描述】:

我已经开始将我的一个应用程序从 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'
.....

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

# 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 文件(保持我的控制器和视图不变!!)或另一种方法来管理这个问题!!

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

弗朗西斯科

【问题讨论】:

    标签: ruby-on-rails-3 ruby-on-rails-4 routes porting custom-routes


    【解决方案1】:

    似乎您在一种方法中逻辑太多。即使在不可接受的 Rails 3 中,我也相当确定。

    如何使用休息路线(rails routing guide 中描述的资源)

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

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

    您的控制器现在将如下所示:

    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

    【讨论】:

    • all.first.first 相同。只需致电.first
    【解决方案2】:

    好吧,伙计们, 我已经解决了... 非常感谢 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
    .....
    

    如您所见,我已在 admin 命名空间内插入 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 %>
    

    再次感谢大家!!

    希望在我阅读本网站的页面时继续向您学习!!

    问候,

    弗朗西斯科

    【讨论】:

    • 如果我是你,我只会重定向到它,而不是呈现索引,这样当用户按 F5 刷新页面时,你不会得到“你想重新提交表单” :)
    • 而且您还可以使用 Flash 消息向用户显示该过程已成功 :) 祝您好运!
    猜你喜欢
    • 2013-01-29
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    相关资源
    最近更新 更多