1

我正在关注 Michael Hartl 关于 Ruby on Rails 的优秀教程,特别是本网站上提供的教程(Rails 版本 3.2)。

我正处于一个点(特别是第 11.2.5 节),其中“关注”和“取消关注”操作被实现为 Ajax 请求。我有两个版本的应用程序代码,一个有效,另一个无效。在其他作品中,我使用其他语法让它工作,我想知道如何或者更确切地说为什么.

这个是在他的网站上找到的:

class RelationshipsController < ApplicationController
  before_filter :signed_in_user

  def create
    @user = User.find(params[:relationship][:followed_id])
    current_user.follow!(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js  { redirect_to @user }   #As suggested by carolclarinet
    end
  end

  def destroy
    @user = Relationship.find(params[:id]).followed
    current_user.unfollow!(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js  { redirect_to @user }   #As suggested by carolclarinet
    end
  end
end

就我而言,它不起作用

但是,相同功能的其他实现(我在教程的官方页面中找到:https://github.com/railstutorial/sample_app_2nd_ed)对我有用:

class RelationshipsController < ApplicationController
  before_filter :signed_in_user

  respond_to :html, :js

  def create
    @user = User.find(params[:relationship][:followed_id])
    current_user.follow!(@user)
    respond_with @user
  end

  def destroy
    @user = Relationship.find(params[:id]).followed
    current_user.unfollow!(@user)
    respond_with @user
  end
end

这是Gemfile教程的github页面中的:

source 'https://rubygems.org'

gem 'rails', '3.2.14'
gem 'bootstrap-sass', '2.1'
gem 'bcrypt-ruby', '3.0.1'
gem 'faker', '1.0.1'
gem 'will_paginate', '3.0.3'
gem 'bootstrap-will_paginate', '0.0.6'
gem 'jquery-rails', '2.0.2'

group :development, :test do
  gem 'sqlite3', '1.3.5'
  gem 'rspec-rails', '2.11.0'
  gem 'guard-rspec', '1.2.1'
  gem 'guard-spork', '1.2.0'
  gem 'childprocess', '0.3.6'
  gem 'spork', '0.9.2'
end

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails', '3.2.5'
  gem 'coffee-rails', '3.2.2'
  gem 'uglifier', '1.2.3'
end

group :test do
  gem 'capybara', '1.1.2'
  gem 'factory_girl_rails', '4.1.0'
  gem 'cucumber-rails', '1.2.1', :require => false
  gem 'database_cleaner', '0.7.0'
  # gem 'launchy', '2.1.0'
  # gem 'rb-fsevent', '0.9.1', :require => false
  # gem 'growl', '1.0.3'
end

group :production do
  gem 'pg', '0.12.2'
end

这是我的`Gemfile:

source 'https://rubygems.org'

gem 'rails', '3.2.11'
gem 'bootstrap-sass', '2.0.0'
gem 'bcrypt-ruby','3.0.1'
gem 'faker','1.0.1'
gem 'will_paginate','3.0.3'
gem 'bootstrap-will_paginate','0.0.6'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

group :development do
    gem 'sqlite3', '1.3.5'
    gem 'annotate', '~> 2.4.1.beta'
end
# Gems used only for assets and not required
# in production environments by default.
group :assets do
    gem 'sass-rails', '3.2.4'
    gem 'coffee-rails', '3.2.2'
    gem 'uglifier', '1.2.3'
end

gem 'jquery-rails', '2.0.2'

group :test, :development do
    gem 'rspec-rails', '2.10.0'
    gem 'guard-rspec', '0.5.5'
    gem 'guard-spork', '0.3.2'
    gem 'spork', '0.9.0'
end 

group :test do
    gem 'capybara', '1.1.2'
    gem 'factory_girl_rails', '1.4.0'
    gem 'cucumber-rails', '1.2.1', require: false
    gem 'database_cleaner', '0.7.0'
    #gem 'shoulda-matchers'
    gem 'launchy'
end 

group :production do
    gem 'pg','0.12.2'
end


#gem 'sqlite3'
#
#
## Gems used only for assets and not required
## in production environments by default.
#group :assets do
#  gem 'sass-rails',   '~> 3.2.3'
#  gem 'coffee-rails', '~> 3.2.1'
#
#  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
#  # gem 'therubyracer', :platforms => :ruby
#
#  gem 'uglifier', '>= 1.0.3'
#end


# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'debugger'

我假设这两个版本(3.2.11 到 3.2.14)之间有显着的语法变化?

这是我在使用3.2.11非工作版本时遇到的错误:

Failure/Error: before { click_button "Follow" }
     ActionController::RoutingError:
       No route matches [GET] "/relationships"
     # (eval):2:in `click_button'
     # ./spec/requests/user_pages_spec.rb:113:in `block (6 levels) in <top 
(required)>'

编辑 1

这是我的config/routes.rb,不应该有任何GET /relationships要求,不是吗?:

SampleApp::Application.routes.draw do
    resources :users do
        member do
            get :following, :followers
        end
    end
    resources :sessions, only: [:new, :create, :destroy]
    resources :microposts, only: [:create, :destroy]
    resources :relationships, only:[:create,:destroy]
  #get "users/new"

 # get "static_pages/home"
 # get "static_pages/help"
 # get "static_pages/about"
 # get "static_pages/contact"

  root to: 'static_pages#home'

  match '/signup', to: 'users#new'
  match '/signin', to: 'sessions#new'
  match '/signout', to: 'sessions#destroy', via: :delete

  match '/help', to: 'static_pages#help'
  match '/about', to: 'static_pages#about'
  match '/contact', to: 'static_pages#contact'

  # The priority is based upon order of creation:
  # first created -> highest priority.

  # Sample of regular route:
  #   match 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  #   match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)

  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', :on => :collection
  #     end
  #   end

  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => 'welcome#index'

  # See how all your routes lay out with "rake routes"

  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
  # match ':controller(/:action(/:id))(.:format)'
end

和输出$rake routes

following_user GET    /users/:id/following(.:format) users#following
followers_user GET    /users/:id/followers(.:format) users#followers
         users GET    /users(.:format)               users#index
               POST   /users(.:format)               users#create
      new_user GET    /users/new(.:format)           users#new
     edit_user GET    /users/:id/edit(.:format)      users#edit
          user GET    /users/:id(.:format)           users#show
               PUT    /users/:id(.:format)           users#update
               DELETE /users/:id(.:format)           users#destroy
      sessions POST   /sessions(.:format)            sessions#create
   new_session GET    /sessions/new(.:format)        sessions#new
       session DELETE /sessions/:id(.:format)        sessions#destroy
    microposts POST   /microposts(.:format)          microposts#create
     micropost DELETE /microposts/:id(.:format)      microposts#destroy
 relationships POST   /relationships(.:format)       relationships#create
  relationship DELETE /relationships/:id(.:format)   relationships#destroy
          root        /                              static_pages#home
        signup        /signup(.:format)              users#new
        signin        /signin(.:format)              sessions#new
       signout DELETE /signout(.:format)             sessions#destroy
          help        /help(.:format)                static_pages#help
         about        /about(.:format)               static_pages#about
       contact        /contact(.:format)             static_pages#contact

没有GET /relationships。然而路由仍在寻找它。

这是我单击“关注”按钮时 Rails 服务器的调试,即当我POST /relationships调用时relationship#create

Started POST "/relationships" for 127.0.0.1 at 2013-10-07 16:41:14 +0200                                                                        [2/649]
Processing by RelationshipsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"4AUIEMLg0nNfnArCvMU9mc7e62hYsfxxHyFyq9EeUxs=", "relationship"=>{"followed_id"=>"95"}, "commit"=>"Fol
low"}
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'sjWCZvhQgP1chbw2uOvw4Q' LIMIT 1
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "95"]]
   (0.0ms)  begin transaction
  SQL (75.3ms)  INSERT INTO "relationships" ("created_at", "followed_id", "follower_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Mon, 07 Oct
 2013 14:41:14 UTC +00:00], ["followed_id", 95], ["follower_id", 1], ["updated_at", Mon, 07 Oct 2013 14:41:14 UTC +00:00]]
   (266.8ms)  commit transaction
Redirected to http://127.0.0.1:3000/relationships
Completed 302 Found in 353ms (ActiveRecord: 343.7ms)


Started GET "/relationships" for 127.0.0.1 at 2013-10-07 16:41:15 +0200

ActionController::RoutingError (No route matches [GET] "/relationships"):
  actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.11) lib/rails/rack/logger.rb:32:in `call_app'
  railties (3.2.11) lib/rails/rack/logger.rb:16:in `block in call'
  activesupport (3.2.11) lib/active_support/tagged_logging.rb:22:in `tagged'
  railties (3.2.11) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.5) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.5) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:in `call'
  railties (3.2.11) lib/rails/engine.rb:479:in `call'
  railties (3.2.11) lib/rails/application.rb:223:in `call'
  rack (1.4.5) lib/rack/content_length.rb:14:in `call'
  railties (3.2.11) lib/rails/rack/log_tailer.rb:17:in `call'
  rack (1.4.5) lib/rack/handler/webrick.rb:59:in `service'
  /home/toni/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
  /home/toni/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
  /home/toni/.rvm/rubies/ruby-1.9.3-p374/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'


  Rendered /home/toni/.rvm/gems/ruby-1.9.3-p374/gems/actionpack-3.2.11/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.5ms)
4

2 回答 2

1

因此,当您通过 ajax 执行此请求时,它会被视为 js 格式:

Processing by RelationshipsController#create as JS

然后在您的控制器的创建操作中,js 没有发生任何事情:

format.js

在没有任何其他指导的情况下,Rails 将为操作执行默认操作,而对于创建,它会重定向到索引操作,即GET /relationships.

如果你告诉 Rails 做一些事情,比如在其他地方重定向或渲染一些东西,它应该可以工作,这就是你发布的代码中发生的事情。

这有帮助吗?

于 2013-10-10T00:01:10.950 回答
1
No route matches [GET] "/relationships

GET当您可能在您的路线文件中将其声明为请求时,您似乎正在发送POST请求。仔细检查。创建方法通常是POST. 您可能需要更改表单操作和/或更改 ajax 请求类型。

为了将来参考,respond_to(:html, :js)对整个控制器的设置与respond_to在方法中使用块相同。它会根据请求的传入方式(即 js -> create.js.erb, html -> create.html.erb )简单地查找视图

于 2013-10-07T11:49:27.803 回答