Rails has_and_belongs_to_many 关系的路由
Rails routing for has_and_belongs_to_many relationship
我正在为一支有球员和球队的运动队开发 rails 4 API,我在 rails 路由和 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
中声明该路由。那么,有几个问题:
- 从 REST-ful 的角度来看,这条路线对人们有意义吗?如果是这样,我将如何在
routes.rb
中声明这条路线
- 应该是 PATCH 还是 POST 将玩家添加到团队的方法?
感谢您提供的任何帮助,
肖恩
您需要使用 nested resource:
#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
参数:
#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
方法——这两种方法都允许您非常简单地从集合中添加和删除对象。
-
Does that route make sense to people from a REST-ful perspective? If so, how would I declare this route in routes.rb
是的。
Should it be a PATCH or a POST method for adding a player to a team?
根据足智多谋的路由结构,我认为您可以通过对 create
操作的 POST
请求逃脱惩罚,但可以通过多种方式完成!
更新
这样做:
#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
您可以这样声明这条路线:
resources :teams, only: [:show, :create, :update, :destroy, :index] do
put 'add_player', on: :member
end
它会将路线映射到您 TeamsController
中的 add_player
操作。
从 REST-ful 的角度来看,我建议您在 players#update
操作中进行此操作,因为您基本上是在更改玩家记录。
我正在为一支有球员和球队的运动队开发 rails 4 API,我在 rails 路由和 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
中声明该路由。那么,有几个问题:
- 从 REST-ful 的角度来看,这条路线对人们有意义吗?如果是这样,我将如何在
routes.rb
中声明这条路线
- 应该是 PATCH 还是 POST 将玩家添加到团队的方法?
感谢您提供的任何帮助,
肖恩
您需要使用 nested resource:
#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
参数:
#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
方法——这两种方法都允许您非常简单地从集合中添加和删除对象。
-
Does that route make sense to people from a REST-ful perspective? If so, how would I declare this route in
routes.rb
是的。
Should it be a PATCH or a POST method for adding a player to a team?
根据足智多谋的路由结构,我认为您可以通过对 create
操作的 POST
请求逃脱惩罚,但可以通过多种方式完成!
更新
这样做:
#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
您可以这样声明这条路线:
resources :teams, only: [:show, :create, :update, :destroy, :index] do
put 'add_player', on: :member
end
它会将路线映射到您 TeamsController
中的 add_player
操作。
从 REST-ful 的角度来看,我建议您在 players#update
操作中进行此操作,因为您基本上是在更改玩家记录。