2015-04-30 2 views
2

Я использую first_or_create для заполнения таблицы списком подписчиков электронной почты (называемых членами). Код выглядит следующим образом:Rails first_or_create! создание нулевых значений в таблице базы данных

def community_members=(members) 
     self.members = members.split(",").map do |member| 
      Member.where(email: member.strip, community_id: self.id).first_or_create! unless member.strip == nil 
     end 
    end 

Все работает отлично, за исключением того, что при добавлении дополнительных писем к одному сообществу, таблица включает колонку «community_id» для всех предыдущих строк на NULL.

Вот лог-сервер:

Member Load (0.2ms) SELECT "members".* FROM "members" WHERE "members"."email" = $1 AND "members"."community_id" = $2 ORDER BY "members"."id" ASC LIMIT 1 [["email", "[email protected]"], ["community_id", 1]] 
    SQL (0.3ms) INSERT INTO "members" ("email", "community_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["email", "[email protected]"], ["community_id", 1], ["created_at", "2015-04-30 16:14:25.930012"], ["updated_at", "2015-04-30 16:14:25.930012"]] 

    Member Load (0.2ms) SELECT "members".* FROM "members" WHERE "members"."community_id" = $1 [["community_id", 1]] 
    SQL (0.4ms) UPDATE "members" SET "community_id" = NULL WHERE "members"."community_id" = $1 AND "members"."id" = 30 [["community_id", 1]] 
    (0.3ms) COMMIT 

Первый груз «член» делает именно то, что он должен делать. Но по какой-то причине он всегда заканчивается загрузкой второго члена, которая входит и устанавливает все поля «community_id» в NULL.

Сейчас я называю: community_member из формы на странице сообщества:

<%= form_for(@community) do |f| %> 
     <%= f.text_area :community_members, class:"form-control input-lg", placeholder:"Please add your list of comma separated member email addresses here" %> 
     <%= f.submit "Save", class: "btn btn-lg btn-green btn-block pad-top" %> 
    <% end %> 

Кажется, я пропускаю что-то очевидное здесь. Есть идеи? Спасибо.

+0

вы можете удалить! from first_or_create !, также я предполагаю, что функция community_members находится в модели сообщества. Не могли бы вы создать это в модели до того, как объект сообщества будет сохранен. – coderhs

+0

Я попытался удалить! и это не имело никакого значения. Объект сообщества уже существует до добавления каких-либо членов, поэтому я не думаю, что он должен быть сохранен? – Lorenz

ответ

1

По-моему, вы захотите найти по уникальному атрибуту, электронной почте и создать по имени сообщества.

Если это так, то вам придется сделать что-то вроде:

Member.where(email: member.strip).first_or_create(community: self) unless... 

Если у вас есть записи с неоднородной электронной почтой, вам придется перестроить свои ассоциации.

class Subscriber 
    #this should have the email attribute 
    has_many :community_subscribers 
    has_many :communities, through: :community_subscribers 
end 

class CommunitySubscriber 
    #this is a 'bridge' table 
    belongs_to :subscriber 
    belongs_to :community 
end 

class Community 
    has_many :community_subscribers 
    has_may :subscribers, through: :community_subscribers 

    #I suggest new method and arg names 
    #Using self will keep the query within the scope of the community you are working on 
    #This also allows for creation of Subscriber records if you insist placing that here 
    #are you sure you want to map instead of just iterating the split list of emails? 
    def new_subscribers(emails) 
    emails.split(",").map do |email| 
     clean_email = email.strip 
     subscriber = Subscriber.where(email: clean_email).find_or_create unless clean_email.blank? 
     self.community_subscribers.where(subscriber: subscriber).first_or_create unless subscriber.blank? 
    end 
end 
end 

Docs: http://apidock.com/rails/v3.2.1/ActiveRecord/Relation/first_or_create http://guides.rubyonrails.org/v3.2.13/active_record_querying.html#first_or_create

+0

Да, мне нужно, чтобы оно было уникальным для сообщества. Таким образом, я мог бы иметь тот же адрес электронной почты, но один с community_id = 1, а другой с community_id = 2. Любые мысли о том, как я могу сделать эту работу? – Lorenz

+0

Хорошо, давайте подумаем о вариантах со «вспомогательными» таблицами. Можем ли мы сделать что-то вроде создания таблицы 'member_community'? Затем мы создаем уникальные «вспомогательные» записи, на которые вы можете положиться на эти ассоциации. Я могу написать это, если вам нужна помощь. –

+0

Вы можете объяснить более подробно? У меня есть таблица участников с сообщениями столбцов и community_id. я довольно новичок в рельсах и работаю с базами данных, поэтому любая деталь поможет много. Спасибо. – Lorenz

Смежные вопросы