2016-10-01 4 views
0

Ich habe drei Modelle: Benutzer, Gruppe und GruppenbenutzerWas ist die beste Vorgehensweise zum Verwalten von Datensätzen in has_many durch Zuordnung?

class User < ActiveRecord::Base 
    has_many :group_users 
    has_many :groups, through: :group_users 

class Group < ActiveRecord::Base 
    has_many :group_users 
    has_many :users, through: :group_users 

class GroupUser < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user` 

und ich schaffen für bestimmte Gruppe mit Kontrollkästchen für alle Benutzer ein Formular, ich kann so sehen, ob jeder Benutzer in der Gruppe ist, und ich kann Überprüfen Sie, ob ein Benutzer zur Gruppe hinzugefügt werden soll, oder deaktivieren Sie, ob der Benutzer der Gruppe angehört. Dann, nachdem ich das Formular abgeschickt habe, bekomme ich ein Array von IDs der Benutzer in der Gruppe.

Meine Frage ist: Was ist der beste Weg, um solche nach dem Senden Vorgang (mehrere hinzufügen/löschen Datensätze) in den Controller oder woanders.

Für diesen Zweck habe ich zwei zusätzliche Aktionen in GroupsController erstellt: def select_users für das Öffnen des Kontrollkästchens Formular und def add_users für Hinzufügungen und Löschungen.

def select_users 
    @group = Group.find(params[:id]) 
    end 

    def add_users 
    @group = Group.find(params[:id]) 
    # Add new users 
    new_users = params[:group][:user_ids] 
    old_users = @group.users.map {|x| x.id.to_s } + [""] 
    add_users = new_users.reject { |item| old_users.include?(item) } 

    add_users.each do |id| 
     @group.users << User.find(id) 
    end 

# Delete unwanted users 
    delete_users = old_users.reject { |item| new_users.include?(item) } 
    @group.group_users.where(user_id: delete_users).destroy_all 

    redirect_to groups_path, notice: 'Users were added.' 

    end` 

Ich konnte Controller Gruppenbenutzer erstellt Tabelle verbinden und setzen die Maßnahmen, bei denen als RESTful ‚neuen‘ und ‚schaffen‘, aber ich bin nicht sicher, es ist am besten Weg zu tun.

+0

Auch 'def select_users' ist ziemlich verwirrend. Wenn du es nennen würdest, würde ich es find_group nennen. Das heißt, es macht keinen Sinn, es zu definieren und es dann nicht in add_users zu verwenden. Wenn Sie so etwas definieren und es in einer früheren Aktion in Ihrem Controller verwenden möchten, wäre das in Ordnung, aber so wie es ist, glaube ich nicht, dass es wirklich hilft. –

Antwort

0

Best Practice ist ein dünn-Controller und ein fettes Modell zu haben. Also würde ich diese beiden Methoden nicht auf Ihren Controller anwenden. Der Controller sollte idealerweise eine einzelne Modellmethode aufrufen. So würde ich das ändern:

def add_users 


@group = Group.find(params[:id]) 
    # Add new users 
    new_users = params[:group][:user_ids] 
    old_users = @group.users.map {|x| x.id.to_s } + [""] 
    add_users = new_users.reject { |item| old_users.include?(item) } 

    add_users.each do |id| 
    @group.users << User.find(id) 
    end 
end 

auf etwas auf dem Gruppenmodell

def update_users(user_ids) 
    new_users = User.where(id: user_ids) 
    final_users = new_users + self.users 
    self.users = final_users.uniq 
    self.save 
end 

Was erholsame Konvention würde ich dies für Gruppen-Controller auf die Update-Aktion setzen und die accepts_nested_attributes_for Option verwenden.

def update 
    @group = Group.find(params[:id]) 
    if @group.update_users(params[:group][:user_ids]) 
    #handle success 
    else 
    #handle error 
    end 
end 
0

1) Machen Sie nicht all diese Dinge im GroupsController - es ist verstopft. Erstellen Sie eine neue einfache Ruby-Klasse, um damit umzugehen.

2) Nicht sicher, aber ich wette, Sie können Benutzer zu einer Sammlung zuweisen und es wird über die Zuordnung schreiben. Als solche:

@group.users = User.where(id: [1,2,4]) # you can just give it your params[:group][:user_ids] here as the array 
@group.save! # also not sure if this is necessary 
+0

Dies ist eine andere gültige Option. Persönlich für das Verhalten in seiner aktuellen Form würde ich kein Formular-Backing-Objekt verwenden. Das heißt, wenn Gruppen komplizierter werden, würde ich ein PORO (einfaches altes Ruby-Objekt) als Formular-Backing-Objekt verwenden. Für mehr darüber, siehe diesen Artikel: https://blog.pivotal.io/labs/labs/form-backing-objects-for-fun-and-profit Ich würde sagen, dass die wahrgenommene Fähigkeit Ebene von OP-Formular unterstützen Objekte sein kann ein bisschen fortgeschritten, aber kein schlechter Weg, dies zu lösen. –

Verwandte Themen