ActiveRecord keeps returning 1 as the Model's id

I am doing a find:

merchant = Merchant.find(:first, :conditions => c, :readonly => false)

I keep getting “id”=>“1” for every single model that is returned.

Since the id is always 1 I can’t do merchant.save without getting
errors.

Anyone have any ideas as to why this is happening?

well, yeah, cos you’re telling it to find the first one. What are you
actually trying to find?

How do I get the actual id of the returned record to be the id in the
model instance? While this may make sense to an experienced Rails
developer I find this most peculiar that the id is not in fact the
actual id of the record returned.

Not sure that’s the problem here… it should return the first record
that matches the conditions. That record could have an id of 1
however.

ice5nake: You haven’t provided enough information. What errors are
you getting when you call save? What are you trying to do? What is
your database and migration for this model?

It is failing on unique validations because, as I suspect, it may be
trying to update the record with id = 1, when in fact the code is
designed to be updating the record where the unique conflict exists.

Does the :first parameter always return 1 as the id?

First of all the id of the model instance should be the id in the
database. Second, the :first parameter just returns the first record
that matches the conditions supplied. If there are no conditions,
then it will always return the record that has id equal to 1.

You should be able to update that record and save it without errors.

What happens when you do Merchant.find(2).id? (it should be 2)

We kind of need more information though, so post up as much code as
you can.

This is most peculiar. It’s definitely returning the correct
information with the exception of the id. import_xml_merchant is
called from a loop. All the merchants have the correct information
with the exception of the id which is always equal to 1.

Here’s an inspect dump of the model.
#<Merchant:0xe9833bc @attributes={“status”=>“1”,
“created_on”=>“2007-10-05 11:13:31”, “name”=>“RollerHockey.com”,
“url”=>“http://www.rollerhockey.com”, “deals_count”=>“86”, “id”=>“1”,
“current_deals_count”=>“0”,
“merchant_id_from_deal_source”=>“K154803”}, @unsaved=false,
@errors=#<ActiveRecord::Errors:0xe95b1c8 @errors={“name”=>[“already
exists”], “url”=>[“already exists”]}, @base=#<Merchant:
0xe9833bc …>>>

#<Merchant:0xe9eeaf4 @attributes={“status”=>“1”,
“created_on”=>“2007-10-05 11:13:31”, “name”=>“Verizon Wireless”,
“url”=>“http://www.verizonwireless.com”, “deals_count”=>“86”,
“id”=>“1”, “current_deals_count”=>“0”,
“merchant_id_from_deal_source”=>“K8669”}, @unsaved=false,
@errors=#<ActiveRecord::Errors:0xe9bc194 @errors={“name”=>[“already
exists”], “url”=>[“already exists”]}, @base=#<Merchant:
0xe9eeaf4 …>>>

def import_xml_merchant(m)
if !@merchants.has_key?(m[‘merchantName’].text)
c = Array.new
c[0] = " 0=0 "
unless m[‘merchantName’].nil?
c[0] += " OR name = ? "
c << m[‘merchantName’].text
end
unless m[‘merchantUrl’].nil?
c[0] += " OR url = ? "
c << m[‘merchantUrl’].text
end
unless m[‘merchant_id_from_deal_source’].nil?
c[0] += " OR merchant_id_from_deal_source = ? "
c << m[‘merchant_id_from_deal_source’].text
end
merchant = Merchant.find(:all, :conditions => c, :limit =>
1, :readonly => false)
if (merchant.empty?)
#Merchant not in system, create a new merchant
merchant = Merchant.new(:name =>
“#{m[‘merchantName’].text}”)
@new_merchants.push(merchant)
else
merchant = merchant.pop
end
merchant.id = merchant.id_before_type_cast
merchant.merchant_id_from_deal_source =
“#{m[‘merchant_id_from_deal_source’].text}” unless
m[‘merchant_id_from_deal_source’].nil?()
unless m[‘merchantUrl’].nil?
merchant.url = “#{m[‘merchantUrl’].text}” unless
m[‘merchantUrl’].text.nil?
end
merchant.name = “#{m[‘merchantName’].text}” unless
m[‘merchantName’].nil?()
merchant.save
@merchants.store(merchant.name,merchant)
return merchant
else
return @merchants[m[‘merchantName’].text]
end
end

why this line?

merchant.id = merchant.id_before_type_cast

It is always going to return the record with id = 1if you have that
0=0 part of the conditions.

Thanks for everyone’s help. This was a stupid mistake on my part.
The first part of my condition was 0=0 follow by OR conditions, which
would always return the first record.

On Jul 17, 2008, at 1:51 PM, ice5nake wrote:

Thanks for everyone’s help. This was a stupid mistake on my part.
The first part of my condition was 0=0 follow by OR conditions, which
would always return the first record.

On Jul 17, 1:26 pm, ice5nake [email protected] wrote:

def import_xml_merchant(m)
if [email protected]_key?(m[‘merchantName’].text)
c = Array.new
c[0] = " 0=0 "
just start with an array having an empty array:
c = [[]]

    unless m['merchantName'].nil?
      c[0] += " OR name = ? "

Then collect the fragments in the first element:
c[0] << ‘name = ?’

      c << m['merchantName'].text
    end
    unless m['merchantUrl'].nil?
      c[0] += " OR url = ? "

c[0] << ‘url = ?’

      c << m['merchantUrl'].text
    end
    unless m['merchant_id_from_deal_source'].nil?
      c[0] += " OR merchant_id_from_deal_source = ? "

c[0] << ‘merchant_id_from_deal_source = ?’

      c << m['merchant_id_from_deal_source'].text
    end

and deal with multiple clauses at the end:
c[0] = c[0].join(’ OR ')

    end
    merchant.save
    @merchants.store(merchant.name,merchant)
    return merchant
  else
    return @merchants[m['merchantName'].text]
  end
end

That will at least fix your conditions problem.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]