On Fri, Aug 21, 2015 at 2:46 PM, masa331 <do...@uol.cz> wrote:

> I don't think it would. You set the id in model, it's passed to database,
> and then database returns it back again
>
>
Some of the database adapters require an additional round-trip to retrieve
the newly-inserted ID; this doesn't happen if an id was supplied at record
creation. Others (like MySQL) will fall back on the DB's built in "last
inserted ID" mechanism, which doesn't work if you are generating IDs
manually (`mysql_insert_id`, for instance, only gets a value if the id
column was AUTO_INCREMENT).

For more detail, keep tracing from where you quoted. `_create_record` calls
`ActiveRecord::Relation#insert`, here:

https://github.com/rails/rails/blob/337684fa28a3e8d55874d5740585710d0fa99ead/activerecord/lib/active_record/relation.rb#L41

which does two things:

* if the primary key is empty and the adapter wants to use prefetch, it
generates an ID

* explicitly selects the supplied (or generated) primary key value and
passes it as a separate argument to the `insert` method in the connection
adapter.

The default implementation of the connection adapter's `insert` method:

https://github.com/rails/rails/blob/337684fa28a3e8d55874d5740585710d0fa99ead/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L107

will automatically return the value passed in as `id_value`, if present.
The MySQL and Postgres versions appear to do this as well.

A workaround for your case would be database-specific; for instance, on
MySQL I'd recommend that you ensure the trigger sets `LAST_INSERT_ID` and
then extract the value from the DB directly (via `SELECT LAST_INSERT_ID()`)
in an `after_create`. Unfortunately, the ID is the one field that the
standard, DB-independent approach to dealing with trigger-supplied data
(calling `reload` after saving) won't work for. :)

--Matt Jones

Dne pátek 21. srpna 2015 17:26:49 UTC+2 masa331 napsal(a):
>
>> Hi guys,
>>
>> this is code from ActiveRecord::Persistance:
>>
>> def _create_record(attribute_names = self.attribute_names)
>> attributes_values = arel_attributes_with_values_for_create(
>> attribute_names)
>>   new_id = self.class.unscoped.insert attributes_values   self.id ||=
>> new_id if self.class.primary_key
>>   @new_record = false   id end
>>
>> I'm curious about the rational behind line no. 5. Why we set `self.id`
>> to value returned from db only if it was previously empty? I couldn't find
>> any test nor some discussion. Also the code dates back to 2011.
>>
>> I work with some legacy db where primary key is string which is modified
>> in some database trigger. Because the `self.id` is set before save it
>> isn't assigned to proper value returned from db after trigger modification.
>>
>> I can't think of any problem if we always assign id to value returned
>> from database.
>>
>> I would love to create PR if it's ok
>>
>> thanks!
>>
>> Sledujte náš blog.uol.cz, facebook.com/uol.cz, gplus.to/uolcz
>> <http://facebook.com/uol.cz>
>
>
> Sledujte náš blog.uol.cz, facebook.com/uol.cz, gplus.to/uolcz
> <http://facebook.com/uol.cz>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rubyonrails-core+unsubscr...@googlegroups.com.
> To post to this group, send email to rubyonrails-core@googlegroups.com.
> Visit this group at http://groups.google.com/group/rubyonrails-core.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to