检查以确保创建新记录包括通过has_and_belongs_to_many创建相关记录的最简单方法是什么?例如,我有:
class Person < ActiveRecord::Base
has_and_belongs_to_many :groups
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :people
end
我希望验证能够在创建新Person时触发,以确保它们属于至少一个组。
另外,我如何在控制器中构建它?现在我有:
def create
@person = current_user.people.new(params[:person])
end
我想让params包含一个组哈希,作为一种嵌套资源。
我查看了Rails文档,但我无法在这个特定情况下找到任何内容。如果有人可以向我解释这个问题或指出我正确的方向,我会非常高兴。谢谢!
答案 0 :(得分:3)
如果要在创建人员期间为用户提供创建一个或多个组的选项,然后验证是否已创建这些组,请指定。否则,此答案的其余部分将专门用于创建一个Person并验证它是否与至少一个现有组相关联。
如果您正在询问如何验证groups_people连接表中是否存在Person-Group关联,则可以使用奇怪的SQL查询来完成此操作,这是不可取的。只要相信经过良好测试的ActiveRecord可以正常工作。
但是,您可以在保存之前验证Person记录中是否存在一个或多个组。
只要您迁移了名为groups_people的连接表:
# db/migrate/xxxxxxxxxxxxxx_create_groups_people
class CreateGroupsPeople < ActiveRecord::Migration
def change
create_table :groups_people, :id => false do |t|
t.string :group_id, :null => false
t.string :person_id, :null => false
end
end
end
# $ rake db:migrate
,你的控制器是正确的:
# app/controllers/people_controller.rb
class PeopleController < ApplicationController
def new
@groups = Group.all
@person = Person.new
end
def create
@person= Person.new(params[:person])
if @person.save
# render/redirect_to and/or flash stuff
else
# render and/or flash stuff
end
end
end
,您已将所有现有的组选项作为复选框:
# app/views/people/new.html.erb
<%= form_for @person do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
# same for other person attributes
<% @groups.each do |g| %>
<%= check_box_tag 'person[group_ids][]', g.id, false, :id => g.group_name_attr %>
<%= label_tag g.group_name_attr %>
<% end %>
<%= f.submit 'Create!' %>
<% end %>
,然后您可以在您的个人记录中验证组的存在:
class Person < ActiveRecord::Base
validates_presence_of :groups
has_and_belongs_to_many :groups
end
有validates_associated helper,但在这种情况下,您不需要将Group.all显示为已选中的选项。
此时不需要accepted_nested_attributes_for。如果您在创建人员时为人员创建了一个组。请再次说明是否属于这种情况。
只需注意:验证包含Group.all作为选项和的传入表单,可以选择与该人一起创建一个组,但这很复杂。它将涉及绕过可能存在的Group模型的现有验证(如果有的话)。