mailchimp_api_v3
mailchimp_api_v3 copied to clipboard
Bug: Nothing is returned when using either `first_or_create` or `find_by`
I have found an issue with the first_or_create
function. If the record doesn't exist, it is created. If the record does exist, it does not return it, but instead throws a Mailchimp::Exception::BadRequest
. Is that what should happen? 🐙
It seems OK for me. I tried something like this:
mailchimp = Mailchimp.connect
mailchimp.lists[0].members.first_or_create name: 'Dominic Sayers'
Internally, first_or_create
calls the find_by
method. Can you repeat your test using find_by
and let me know if this also throws an exception?
Could you also share some code to give more details of how you were using the first_or_create
method?
Right, back to this now. I was wrong, it throws a Mailchimp::Exception::Duplicate
, which is expected, but ideally a record should be returned, right? I see the return
line here.
There are no errors if I use find_by
, but nothing is returned. :suspect:
@emails.each do |email|
attributes = {
"email_address": email,
"status": "subscribed"
}
record = MAILCHIMP.lists('0719f1b43e').members.find_by(attributes)
puts record
end
I have previously gotten around it by manually going through the members list and checking if a record exists. The record is updated if it does, otherwise a new record is created...
def update_member
memberFound = false
list = MAILCHIMP.lists('0719f1b43e')
list.members.find_each do |member|
if member.email_address == @email
# Update the merge fields
member.update merge_fields: member_attributes[:merge_fields]
# Update the interest group
member.update interests: member_attributes[:interests]
memberFound = true
end
end
if memberFound == false
MAILCHIMP.lists('0719f1b43e').members.first_or_create(member_attributes)
end
end
I think I may know why nothing is returned...
#L32: Shouldn't that be return instances
?
#L37: Shouldn't that be instances ? return instances.first : return nil
?
I can't remember in ruby if stating a variable alone (like #L32) automatically returns the value.
No, Ruby returns the last thing that was evaluated in the method. It's normal Ruby style to not use return
unless you want to return early from a method.
On the more substantive point, I copied your code fragment into a script and ran it:
MAILCHIMP = Mailchimp.connect
@emails = ['[email protected]']
@emails.each do |email|
attributes = {
"email_address": email,
"status": "subscribed"
}
record = MAILCHIMP.lists('e0fd0bddcb').members.find_by(attributes)
puts record
end
and it output
<[email protected]>
as expected.
Arr I think I know why... What does the angle brackets mean? As it outputs as nothing ('nil') in the logs. I know there is something there because I have tried puts record.nil?
, which returns 'false'.
If I run puts record
in the rails console, I get...
<[email protected]>
=> nil
If I run puts 'Account: ' + record
in the rails console, I get...
TypeError: no implicit conversion of Mailchimp::List::Member into String
As the result is 'nil', I think that is why I don't see the output in the log.
The same happens for both
find_by
andfirst_or_create
puts record
explicitly invokes the to_s
method of Mailchimp::List:Member
(#L50-L52)
'Account: ' + record
might imply a different sort of addition and Ruby complains in case you meant something different.
Ar okay. So how can I get puts
to output the string to the log instead of the result 'nil'?
What I cannot get my head around is why first_or_create
throws Mailchimp::Exception::Duplicate
when run via my controller, but not when run via the rails console (when the member already exists on the list).