Recently I've found out some mentions to the "--sandbox" parameter to
the "rails console" command.
And I found the idea interesting, but since I'm using Sequel instead of
ActiveRecord I guessed this wouldn't work for me.
But after talking about this subject in the Sequel mailing list, Jeremy
Evans has brought to my attention that there are some issues with the
current approach taken by ActiveRecord.
In case you're curious about the full thread:
https://groups.google.com/forum/?fromgroups#!msg/sequel-talk/VjfJcTD6s3w/Lbrc2RqVuu8J
<https://groups.google.com/forum/?fromgroups#%21msg/sequel-talk/VjfJcTD6s3w/Lbrc2RqVuu8J>
Here is how sandbox is handled by ActiveRecord:
activerecord/lib/active_record/railties/console_sandbox.rb:
ActiveRecord::Base.connection.increment_open_transactions
ActiveRecord::Base.connection.begin_db_transaction
at_exit do
ActiveRecord::Base.connection.rollback_db_transaction
ActiveRecord::Base.connection.decrement_open_transactions
end
This only handles the default database as noticed by Jeremy. If you have
models relying on different databases, only the default one will be
sandboxed.
Additionally, there is another design issue. For example, Sequel was
designed in a way that it won't allow users to directly manipulate
connections and control where to start and end transactions. So it only
provides a block-based approach:
Here is how this would be implemented in Sequel (assuming a decent
database like PostgreSQL that supports savepoints - if that is not the
case, just remove the :savepoint option):
DB.transaction(savepoint: true, rollback: :always) do
# sandboxed database access here:
u = User[1]
u.name = 'Changed'
u.save_changes
end
I have a similar issue with the design of RSpec lack of an around(:all)
filter similar to around(:each) that won't allow me to use savepoints to
restore the database state when creating common data in a before(:all)
section of some contexts.
Sequel does support an "after_connect" hook so that it could be used to
make sure the connection is inside a transaction when it is created.
Maybe ActiveRecord could provide something similar and use it instead
for dealing with a sandboxed application.
Another issue with the current approach is that if you change some
database data inside a thread, I guess it would spawn a new connection
that wouldn't be sandboxed. Is that right?
Any thoughts about this?
Cheers,
Rodrigo.
--
You received this message because you are subscribed to the Google Groups "Ruby on
Rails: Core" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.