mailchimp_api_v3 icon indicating copy to clipboard operation
mailchimp_api_v3 copied to clipboard

Bug: Nothing is returned when using either `first_or_create` or `find_by`

Open ckhatton opened this issue 7 years ago • 10 comments

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? 🐙

ckhatton avatar Mar 01 '17 22:03 ckhatton

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?

dominicsayers avatar Mar 07 '17 09:03 dominicsayers

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

ckhatton avatar Mar 07 '17 16:03 ckhatton

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

ckhatton avatar Mar 07 '17 17:03 ckhatton

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.

ckhatton avatar Mar 15 '17 10:03 ckhatton

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.

dominicsayers avatar Mar 15 '17 11:03 dominicsayers

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.

dominicsayers avatar Mar 15 '17 11:03 dominicsayers

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 and first_or_create

ckhatton avatar Mar 15 '17 12:03 ckhatton

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.

dominicsayers avatar Mar 15 '17 12:03 dominicsayers

Ar okay. So how can I get puts to output the string to the log instead of the result 'nil'?

ckhatton avatar Mar 15 '17 12:03 ckhatton

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).

ckhatton avatar Mar 15 '17 12:03 ckhatton