1
votes

Valider l'appartenance de la ressource HABTM à la même organisation

J'ai une relation HABTM entre les utilisateurs et les évaluations et ils appartiennent tous les deux à une organisation, lorsqu'un utilisateur administrateur tente de créer une évaluation, je veux valider que les utilisateurs sélectionnés (plusieurs utilisateurs peuvent être sélectionnés via une case à cocher) appartiennent à l'organisation sélectionnée sous la forme

Modèle utilisateur

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

Modèle d'évaluation

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

Modèle d'organisation

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

Voici ce que j'ai essayé mais ne fonctionne pas correctement car je ne suis pas sûr d'obtenir le paramètre utilisateur

class Assessment < ApplicationRecord
  has_and_belongs_to_many :users
end

Ci-dessous le formulaire

  # 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


6 commentaires

essayez quelque chose comme organization.users.where (id: user.id) .exists?


J'obtiens ce message d'erreur utilisateur de méthode non valide, vouliez-vous dire utilisateurs @fanta


ce code doit entrer dans votre méthode validate_users (user) . Là, vous avez l'objet user .


ne fonctionne toujours pas, j'essaie de m'assurer que les utilisateurs sélectionnés appartiennent à l'organisation sélectionnée


cela devrait fonctionner, si l'organisation que vous utilisez dans la méthode validate_user est celle avec laquelle vous validez, alors cela devrait fonctionner car organization.users donnerait vous les utilisateurs qui appartiennent à cette organisation, et le recherche simplement dans cette collection. Si cela ne fonctionne pas, nous aurions besoin de plus de détails (code) sur la façon dont vous le faites.


peut-être pourriez-vous montrer le code complet qui, selon vous, fonctionnera s'il vous plaît @fanta


3 Réponses :


0
votes

Essayez :

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

Ce qui précède suppose que vous voulez qu'une évaluation sans utilisateur soit valide.


3 commentaires

Cela ne semble pas fonctionner, je dois valider que les utilisateurs sélectionnés existent également dans l'organisation sélectionnée


C'est ce que je pense de ce qui précède, organisation.user_ids vous listera chaque user_id dans l'organisation, puis vous vérifierez si ce tableau inclut tous les user_ids associés à l'évaluation


Cela ne fonctionnera pas car include? vérifie si l'objet spécifié est dans le tableau et que l'objet peut être n'importe quoi. Par exemple: [1,2,3] .include? ([1,2]) est faux, alors que [[1,2], 3] .include? ([1, 2]) est vrai



0
votes

Lors de la soumission du formulaire, vous recevrez un organization_id dans les paramètres et un tableau user_ids.

Commencez par trouver l'organisation, puis vérifiez si les user_ids de cette organisation incluent les user_ids que vous avez reçus dans les paramètres.

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

Le user_ids-org.user_ids compare les 2 tableaux. Si le premier tableau contient des éléments que le deuxième tableau n'a pas, il renverra un tableau avec ces éléments.


1 commentaires

Votre réponse était assez proche, juste le Organization.find (organization_id) qui a renvoyé un message d'erreur, merci quand même @Hackman



1
votes

Vous devez tester si les utilisateurs associés figurent dans la liste des utilisateurs de l'organisation. Vous pouvez le faire en soustrayant les user_ids de l'organisation de ceux de l'évaluation. Si le résultat n'est pas un tableau vide, alors il y a des utilisateurs en dehors de l'organisation.

S'il y a des utilisateurs en dehors de l'organisation, alors vous devez ajouter au tableau d'erreurs de l'objet pour le déclarer invalide:

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

REMARQUE: j'ai supposé que vous pouviez avoir une relation appartient_to entre Assessment -> Organization puisque vous avez déjà le has_many correspondant dans l'organisation. Si ce n'est pas le cas, vous devrez obtenir les ID utilisateur de l'organisation appropriée d'une manière différente.

Voir https://guides.rubyonrails.org/active_record_validations.html#custom-methods pour plus de détails sur les méthodes de validation personnalisées.


0 commentaires