Rails检查嵌套属性项是唯一的

时间:2015-05-25 06:41:20

标签: ruby-on-rails nested-attributes

我有一个问题,开始让我的头受伤。我可以看到一个解决方案,但只需要一只手就可以了解,或者是一个完全不同的解决方案。

我正在使用rails 4,我有3个型号。

  • 项目(has_many_users通过协作者,has_many_collaborators)
  • 用户(has_many_projects通过协作者,有很多合作者)
  • 协作者(将用户与项目连接起来)

协作者通过jquery添加到项目中,通过搜索用户然后将用户的ID添加到DOM,以便嵌套属性做到这一点。

这一切都有效,但问题是协作者有角色,每个协作者可能在同一个项目中有多个角色。例如,某人可能被列为项目不同部分的摄影师和作家。

目前正在为每个新人/角色添加新的协作者,例如John被添加为摄影师,然后在后面的部分中John被添加为作家。

我想要做的是检查协作者是否已经存在,如果是,则更新嵌套属性而不是创建新属性。

执行此操作的一个选项是在用户查找后使用Jquery并执行第二次ajax调用以检查是否存在具有项目ID和用户ID的协作者,如果存在,则将协作者ID添加到dom以触发正常的嵌套属性行为。

然而,这只是一种非常笨重的方法。如果第二个ajax调用失败会发生什么?而且这也意味着因为协作者被添加到应用程序的许多部分中,所以这个jquery / hidden字段代码将不得不多次添加。不是很干。

更有意义的是在项目模型或控制器中添加方法,检查协作者是否已存在。

我要做的是循环协作者的嵌套属性,并添加协作者的ID(如果它已经存在)。

我假设我需要查询协作者的project_id和user_Id,如果我得到匹配,那么为协作者添加id属性?

project.rb

def collaborators_attributes=(attrs)
  self.attributes.each do |key,value|

    #How do I check and update the id attribute 

  end      
end

这种方法可能是完全错误的方向,所以对它的任何帮助,或者新方法都非常赞赏。

2 个答案:

答案 0 :(得分:0)

您可以尝试find_or_initialize_by

collaborator = Collaborator.find_or_initialize_by(project_id: project_id, user_id: user_id)
collaborator.update_attributes(Hash)

答案 1 :(得分:0)

好的,这是我到目前为止所做的工作

project.rb

#Modify collaborators before save
def collaborators_attributes=(attrs)
  attrs.each do |key,value|
    #loop through collaborators and check if they already exist 
    if Collaborator.where("project_id = ? AND user_id = ?", @attributes["id"], value["user_id"] ).present?
      #if they do exist, add the collaborator id to the attributes
      attrs[key]["id"] = Collaborator.where("project_id = ? AND user_id = ?", @attributes["id"], value["user_id"] ).first.id 
      #I'm adding the project id here, but it may not be required
      attrs[key]["project_id"] = @attributes["id"]
    end
  end 
  #update or create new - based on of a collaborator id passed in attrs
  assign_nested_attributes_for_collection_association(:collaborators, attrs)
end

这感觉非常混乱,但似乎有效。我抓住嵌套属性并循环遍历每个协作者以检查它们是否存在。如果他们这样做,我将协作者ID添加到属性。然后我通过assign_nested_attributes_for_collection_association

更新或创建新的

目前唯一的问题是,如果我删除了一个协作者,它会将它们从整个项目中删除,因为它应该真的只是将它们标记为摄影师,作家等。我可以通过类似的循环来检查它如果添加任何角色,但这一切都开始变得难以做到。我想我会回到绘图板并考虑打破模型,以便合作者加入用户和项目,并且合作者可以拥有每个角色中的一个,例如摄影师,作家等。

  User
     Collaborator
         Photographer
         Writer
         Ect
  Project