Rails为has_and_belongs_to_many关系路由

我正在为一个运动队工作一个rails 4 API,我有球员和球队,而且我在使用rails routing和has_many关系方面有点挣扎。 我和球员之间的关系看起来像:

 class Team < ActiveRecord::Base extend Searchable validates :title, presence: true has_and_belongs_to_many :players end class Player < ActiveRecord::Base extend Searchable validates :first_name, presence: true validates :last_name, presence: true has_and_belongs_to_many :teams end 

我希望能够将现有的玩家添加到团队中,但我不确定如何更改我的routes.rb文件。 目前,它看起来像:

 Rails.application.routes.draw do devise_for :users namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do scope module: :v1 do resources :users, :only => [:show, :create, :update, :destroy] resources :teams, :only => [:show, :create, :update, :destroy, :index] resources :players, :only => [:show, :create, :update, :destroy, :index] resources :sessions, :only => [:create, :destroy] end end end 

允许对玩家和团队模型进行CRUD操作。 我在考虑将球员添加到现有球队,我的路线需要看起来像:

 /teams/:team_id/add_player/ 

但我不确定如何在routes.rb声明该路由。 所以,有几个问题:

  1. 从REST-ful的角度来看,这条路线对人们有意义吗? 如果是这样,我将如何在routes.rb声明此路由
  2. 它应该是一个PATCH还是POST方法,用于将球员添加到球队?

感谢您提供的任何帮助,

肖恩

你可以像这样声明这条路线:

 resources :teams, only: [:show, :create, :update, :destroy, :index] do put 'add_player', on: :member end 

它会将路径映射到add_player中的TeamsController

从REST-ful的角度来看,我建议你在players#update动作中做到这一点,因为你基本上是在改变玩家记录。

您需要使用嵌套资源 :

 #config/routes.rb resources :teams, only: [....] do resources :players, path: "", path_names: {new: "add_player", create: "add_player", destroy: "remove_player" }, only: [:create, :destroy] #-> /v1/teams/:team_id/add_player end 

这将路由到你的players_controller ,传递:team_id param:

 #app/controllers/players_controller.rb class PlayersController < ApplicationController def new @players = Player.all end def create if params[:team_id] @team = Team.find params[:team_id] @player = Player.find params[:id] @team.players << player else # normal "create" action end end def destroy if params[:team_id] @team = Team.find params[:id] @player = Player.find params[:id] @team.players.delete player end end end 

您可以将此与以下视图结合使用:

 #app/views/players/new.html.erb <%= form_tag team_players_path do %> #-> method should be "post" <%= collection_select :player, :id, @players, :id, :name %> <%= submit_tag %> <% end %> 

-

琐事:

使用HABTM,您可以获得<<collection.delete方法 - 两者都允许您简单地添加和删除集合中的对象。

-

从REST-ful的角度来看,这条路线对人们有意义吗? 如果是这样,我将如何在routes.rb声明此路由

是的。

它应该是一个PATCH还是POST方法,用于将球员添加到球队?

根据资源丰富的路由结构,我会说你可以通过POST请求来create动作,但它可以通过多种方式完成!


更新

做这个:

 #config/routes.rb resources :teams, only: [....] do match "players/:id", to: "players", via: [:put, :delete] end 

这将创建以下路由:

 #put url.com/teams/:team_id/players/:id #destroy url.com/teams/:team_id/players/:id 

这将允许您在teams控制器中使用players方法:

 #app/controllers/teams_controller.rb class TeamsController < ApplicationController def players @team = Team.find params[:team_id] @player = Player.find params[:id] if request.put? @team.players << player elsif request.delete? @team.players.destroy player end end end