2016-03-31 9 views
3

Ich habe zwei Modelle Group und Person. Beide sind HABTM, aber ich möchte, dass sich eine Person aus einer bestimmten Gruppe abmeldet, ohne diese Gruppe zu löschen, nur die Person aus der Gruppe. Ich habe versucht, das in der Konsole herauszufinden, und ich kann es nicht verstehen. Ich zeige meinen Code zur Klärung.Löschen eines einzelnen Benutzers in einer Gruppe - Active Record

Ich mache diese Methode derzeit

def delete_from_group(phone_number) 
person = Person.find_by(phone_number: phone_number) 
person.groups.destroy 
end 

dies mein Controller ist.

def create 
# Grab the phone number from incoming Twilio params 
@phone_number = params[:From] 
# Find the subscriber associated with this number or create a new one 
@subscriber = Person.find_or_create_by(phone_number: @phone_number) 
@delete_group = Person.find_by(phone_number: @phone_number) 

# Update location data 
@subscriber.update(
    city: params[:FromCity], 
    state: params[:FromState], 
    zip: params[:FromZip], 
    country: params[:FromCountry] 
) 

@body = params[:Body].to_s.downcase.strip 
begin 
    # Process the command from our Subscriber 
    output = process_message(@body, @subscriber, @delete_group) 
rescue 
    output = "Something went wrong. Try again." 
end 

# Render the TwiML response 

respond(output) 
end 

private 

def process_message(message, subscriber, delete_group) 
if worker_groups.include?(message) 
    subscriber.update(subscribed: true) 
    subscriber.add_to_group(message) 
    "You have been subscribed to the #{message.capitalize} list" 

elsif message == "stop volunteer" 
    delete_group.delete_from_group("volunteer") 
    "You have been unsubscribed from the specified list" 
elsif message == "stop dancer" 
    delete_group.delete_from_group("dancer") 
    "You have been unsubscribed from dancer list" 
elsif message == "stop staff" 
    delete_group.delete_from_group("staff") 
    "you have been unsubscribed from staff list" 

elsif message == "tulip" || message == "stem" 
    subscriber.update(subscribed: message == "tulip") 
    subscriber.add_to_group("visitor") 

    if subscriber.subscribed 
    "You are now subscribed for updates." 
    else 
    "You have unsubscribed from notifications. Text 'TULIP' to start receieving updates again." 
    end 
else 
    "Sorry, we don't recognize that command. Available commands are: 'TULIP' or 'STEM'." 
end 
end 

def worker_groups 
%w(dancer staff volunteer) 
end 

def worker_groups 
%w(dancer staff volunteer) 
end 
+0

Wir werden mehr Informationen benötigen, wie '' Person' und Group' verbunden sind. Kann helfen zu zeigen, was die Methode 'add_to_group' macht, oder zeigt die Assoziation in jedem Modell. – MTarantini

Antwort

7

, wenn Sie die Gruppen-ID Sie als Variable group_id entfernen möchten haben:

person = Person.find_by(phone_number: phone_number) 
group = person.groups.find(group_id) 

if group 
    person.groups.delete(group) 
end 

Siehe this awesome post on the subject

Auch die Rails documentation sehen:

collection.delete (Objekt , ...) Entfernt ein oder mehrere Objekte aus der Sammlung, indem sie ihre Zuordnung entfernen aus der Join-Tabelle. Diese zerstört die Objekte nicht.

+1

Würde das die Gruppe nicht löschen? Die Frage ist, wie man eine Person aus der Gruppe entfernt, ohne sie zu löschen. – MTarantini

+0

Wenn Sie den Beitrag und die Dokumentation lesen (oben hinzugefügt), ist es klar, dass es nur aus der Sammlung gelöscht wird. – jmkoni

+0

Rückwärts ... entfernt es aus der Sammlung, indem es die ASSOCIATIONS entfernt. Es zerstört die Gruppe nicht. – jmkoni

2

können Sie entfernen die Group Verbände auf diese Weise:

person.groups = [] 
person.save 

Oder:

person.update(groups: []) 
+1

Nur um klar zu sein, würde dies die Person aus ALLEN Gruppen entfernen.Wenn das die Absicht ist, dann ist dies eine effektive Lösung. – jmkoni

3

I has_many :through statt HABTM verwenden würde. Damit können Sie die Join-Tabellenzeile direkt löschen und Metadaten zur Join-Tabelle hinzufügen.

Sofern Sie ein konventionelles Setup haben, müssen Sie lediglich die Tabelle umbenennen und die Beziehungsdefinitionen auf den Modellen ändern.

Die Umbenennung wird aufgrund der Art und Weise benötigt, in der ActiveRecord Klassennamen aus Tabellen auflöst. ActiveRecord versucht, Groups::People zu laden, wenn die Tabelle groups_people benannt wird. GroupPeople ist einfach seltsam, also lasst uns mit Membership gehen.

class Person < ActiveRecord::Base 
    has_many :memberships 
    has_many :groups, through: :memberships 
end 

class Group < ActiveRecord::Base 
    has_many :memberships 
    has_many :people, through: :memberships 
end 

class Membership 
    belongs_to :group 
    belongs_to :person 
    validates_uniqueness_of :group_id, scope: :person_id 
end 

Sie können nun Zeilen entfernen direkt aus dem Modell Verein beitreten:

person.memberships.find_by(group_id: 5).destroy 
+0

Dies kann als eine ziemlich triviale Verbesserung erscheinen, aber HABTM funktioniert nur wirklich für die einfachsten möglichen Beziehungen und Sie müssen in der Regel irgendwann zu 'has_many: through' wechseln. http://blog.flatironschool.com/why-you-dont-need-has-and-belongs-to-many/ – max

+0

Ich weiß, ich habe eine andere Antwort auf diese Frage, aber wenn Sie die Zeit haben, diese Änderung has_many zu machen : durch wirklich ist der bevorzugte Weg, um darüber zu gehen. Upvoted diese Lösung. – jmkoni