2016-03-31 60 views
3

我有兩個模型GroupPerson。都是HABTM,但我希望一個人能夠在不刪除該組的情況下退出特定組,而不是刪除該組。我一直試圖在控制檯中弄清楚這一點,我似乎無法得到它。我會顯示我的代碼進行澄清。刪除組中的單個用戶 - 活動記錄

我做這個方法目前

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

這是我的控制器。

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

我們需要了解如何'Person'和'Group'連接的更多信息。可能有助於顯示add_to_group正在執行的方法,或者顯示每個模型中的關聯。 – MTarantini

回答

7

,如果您有要刪除可變GROUP_ID組ID:

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

if group 
    person.groups.delete(group) 
end 

this awesome post on the subject

另請Rails documentation

collection.delete(對象,...)刪除 集合中的一個或多個對象,方法是刪除它們的關聯從連接表中刪除。這 不會銷燬對象。

+1

這不會刪除組?問題是如何在不刪除人的情況下將其從人羣中刪除。 – MTarantini

+0

如果您閱讀文章和文檔(上面已添加),很明顯它只是將其從集合中刪除。 – jmkoni

+0

向後......通過刪除它們的ASSOCIATIONS將其從集合中刪除。它不會破壞團體。 – jmkoni

2

可以刪除Group協會這樣:

person.groups = [] 
person.save 

或者:

person.update(groups: []) 
+1

要清楚,這將從所有組中刪除該人員。如果這是意圖,那麼這是一個有效的解決方案。 – jmkoni

3

我會用has_many :through代替HABTM。這可讓您直接刪除連接錶行,並在連接表上添加元數據。

如果您有一個常規設置,只需重命名該表並更改模型上的關係定義即可。

class RenameGroupsPersons < ActiveRecord::Migration 
    def change 
    rename_table :groups_people, :memberships 
    end 
end 

由於ActiveRecord從表中解析類名,所以需要重命名。如果表名爲groups_people,ActiveRecord將嘗試加載Groups::PeopleGroupPeople只是奇怪,所以讓我們去與Membership

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 

現在你可以直接從連接模型協會刪除行:

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

這似乎是一個很小的改進,但HABTM只能用於最簡單的關係,而且通常需要在某個時刻切換到'has_many:through'。 http://blog.flatironschool.com/why-you-dont-need-has-and-belongs-to-many/ – max

+0

我知道我對這個問題有另一個答案,但是如果你有時間做這個改變has_many :通過真的是最好的方式去做這件事。 Upvoted這個解決方案。 – jmkoni