验证HABTM资源属于同一组织

时间:2019-06-14 14:21:21

标签: ruby-on-rails

我在用户和评估之间具有HABTM关系,它们都属于一个组织,当管理员用户尝试创建评估时,我想验证所选用户(可以通过复选框选择多个用户)是否属于到所选组织的形式

用户模型

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable

  has_and_belongs_to_many :assessments, optional: true
  belongs_to :organization, optional: true
end

评估模型

class Assessment < ApplicationRecord
  has_and_belongs_to_many :users
end

组织模式

class Organization < ApplicationRecord
  has_many :users
  has_many :assessments, through: :participants
end

这是我尝试过的操作,但由于不确定是否要获取用户参数而无法正常工作

 def validate_users(user)
   organization.users.include?(user) == true
 end

下面是表格

form do |f|
 f.inputs do
   f.input :title, as: :string
   f.inputs 'Assign Users' do
     f.input :users, as: :check_boxes, collection: User.all
   end

     f.input :organization, collection: Organization.all
 end

 f.actions
end

3 个答案:

答案 0 :(得分:1)

您需要测试关联的用户是否在组织的用户列表内。您可以通过从评估中减去组织的user_id来实现。如果结果不是一个空数组,则表示该组织之外的用户。

如果组织外部有用户,则需要添加到对象的错误数组以将其触发为无效:

class Assessment < ApplicationRecord
  has_and_belongs_to_many :users
  belongs_to :organization

  validate :users_in_organization

  def users_in_organization
    org_user_ids = organization.try(:user_ids) || [] # catches if there is no organization
    errors.add(:users, "not in organization's users") if (user_ids - org_user_ids).present?

  end
end

注意::我假设您可以在评估->组织之间建立belongs_to关系,因为您已经在组织中拥有相应的has_many。如果不是这种情况,则需要以其他方式获取相应组织的用户ID。

有关自定义验证方法的详细信息,请参见https://guides.rubyonrails.org/active_record_validations.html#custom-methods

答案 1 :(得分:0)

尝试:

class Assessment < ApplicationRecord
  has_and_belongs_to_many :users
  validate :users_are_in_same_org?

  def users_are_in_same_org?
    return true unless users.any?

    organisation.user_ids.include?(user_ids)
  end
end

以上假设您希望没有用户的评估有效。

答案 2 :(得分:0)

提交表单时,您将在params中收到一个organization_id和一个user_ids数组。

首先找到组织,然后检查该组织的user_id是否包含您在参数中收到的user_id。

class Assessment < ApplicationRecord
  has_and_belongs_to_many :users
  validate :organization_includes_users

  def organization_includes_users
    org = Organization.find(organization_id)
    if user_ids-org.user_ids == []
      return true
    else
      return false
    end
  end
end

user_ids-org.user_ids比较两个数组。如果第一个数组包含第二个数组不包含的元素,则它将返回包含这些元素的数组。