Ruby on rails 3 在Rails3中,用RESTful方式将一个实体添加到另一个实体(n:m关系)中?

Ruby on rails 3 在Rails3中,用RESTful方式将一个实体添加到另一个实体(n:m关系)中?,ruby-on-rails-3,rest,has-and-belongs-to-many,Ruby On Rails 3,Rest,Has And Belongs To Many,这可能是一个非常简单的问题,有一个简单的解决方案,但我还没有得到它 假设我有以下两种模型: class Task has_and_belongs_to_many :users end class User has_and_belongs_to_many :tasks end 进一步假设有一个id为1的名为“wayne”的用户和一个id为2的名为“go shopping”的任务。通过REST接口创建它们之间关系的RESTful方法是什么 添加像users/1/add_task/2这

这可能是一个非常简单的问题,有一个简单的解决方案,但我还没有得到它

假设我有以下两种模型:

class Task
   has_and_belongs_to_many :users
end

class User
   has_and_belongs_to_many :tasks
end
进一步假设有一个id为1的名为“wayne”的用户和一个id为2的名为“go shopping”的任务。通过REST接口创建它们之间关系的RESTful方法是什么

添加像users/1/add_task/2这样的路由更像RPC风格,并且不是很RESTful。那么你会怎么做呢?

你可以选择

用户/{userid}/tasks/

其中,对该位置的PUT将具有{taskid}的任务添加到集合中;您还可以(同时)拥有

任务/{taskid}/用户/


放置到该位置会向集合中添加一个具有{userid}的用户。

您认为这个解决方案怎么样

编辑:将用户替换为AssignmentSheet,将任务替换为本例中的Assignment,以适合原始问题

一些路线:

# routes.rb
put "assignment_usage/assignment_sheet/:assignment_sheet_id/assignment/:assignment_id" => "assignment_usage#create"
  delete "assignment_usage/assignment_sheet/:assignment_sheet_id/assignment/:assignment_id" => "assignment_usage#destroy"
以及控制器代码:

# app/controllers/assignment_usage_controller.rb
class AssignmentUsageController < ApplicationController
  before_filter :load_instances

  # PUT /assignment_usage/assignment_sheet/:assignment_sheet_id/assignment/:assignment_id
  def create
    @assignment.assignment_sheets << @assignment_sheet
    redirect_to(@assignment_sheet, :notice => "Assignment has been successfully added.")
  end

  # DELETE /assignment_usage/assignment_sheet/:assignment_sheet_id/assignment/:assignment_id
  def destroy
    @assignment.assignment_sheets.delete @assignment_sheet
    redirect_to(@assignment_sheet, :notice => "Assignment has been successfully removed.")
  end

  private
  def load_instances
    @assignment_sheet = AssignmentSheet.find(params[:assignment_sheet_id])
    @assignment       = Assignment.find(params[:assignment_id])
  end
end
#app/controllers/assignment_usage_controller.rb
类AssignmentUsageController“已成功删除分配”。)
结束
私有的
def load_实例
@assignment\u sheet=AssignmentSheet.find(参数[:assignment\u sheet\u id])
@assignment=assignment.find(参数[:assignment\u id])
结束
结束

也许使用一个单独的资源更清楚一些。

restful方法是添加一个用作连接的模型。然后jointable将获得自己的资源。 连接模型可以称为Subscription,或者,如果找不到合适的名称,就称它为TaskUser。 导轨的这一部分与以下内容相关:

在声明路由后(例如,通过在routes.rb中添加
resource TaskUser
),向/taskusers提交带有
user\u id
task\u id
帖子时,可以在两个对象之间创建链接。控制器应包括如下内容:

class TaskUsersController
  def create
    TaskUser.create(:task_id => params[:task_id], :user_id => params[:user_id])
  end
end
然后,只需调用

user.tasks
就我个人而言,我认为在某些情况下,您不需要此解决方案,因为它会为附加模型和所有这些带来相当大的开销

例如,我有一个项目模型,希望向其添加标记。这是一个由
声明的多对多关联,在每个模型中都有_和_属于_-many
,但我总是在项目中添加一个标记,而不是相反,因此前一种解决方案似乎有点过分。然后我就加上

put "/Items/#{item_id}/tags/#{tag_id}" => "items#add_tag"
到routes.rb。项目控制器:

class ItemController
  def add_tag
    item = Item.find_by_id(:item_id)
    tag = Tag.find_by_id(:tag_id)
    item.tags << tag
    item.save
  end
end
类项目控制器
def添加标签
项目=项目。按项目id查找项目(:项目id)
tag=tag.find_by_id(:tag_id)

item.tags我是否正确,我必须手动添加此路由,并将一些代码添加到相应的控制器中以使其工作?
class ItemController
  def add_tag
    item = Item.find_by_id(:item_id)
    tag = Tag.find_by_id(:tag_id)
    item.tags << tag
    item.save
  end
end