There are times when it would be very useful to be able to get the Arel for any given ActiveRecord action such as a creation or update without actually carrying out the action.
The use case would be using AR semantics to define an action, but then using that in a larger context, such as concatenating the SQL for several updates together using “;” and executing them in a single round-trip to the server. Technically, this just means just needing the SQL, but it seems silly to provide the SQL rather than the Arel from which the SQL can be trivially retrieved.
I just had a similar need the other day, where I needed to build a separate query based on the current scope (not clone the current scope, but take the specific parameters of the scope to apply to another query which wasn’t a scope at all). The way I had to do what I needed was to grab the current scope and manually inspect the where_values, joins_values, etc.
I think this is way too specific for core. Looks like a great idea for a plugin, though
I don’t disagree that this may be too specific for core. Just demonstrating that I think there’s a need, so might make a good gem.
Could that be done as a plugin and not rely on undocumented internal APIs that are likely to change without warning?
I would think so. Looking at the AR code for creating a record,
which is just doing this (and note this method is protected, not private):
attrs = {}
arel_table = self.class.arel_table
attribute_names.each do |name|
attrs[arel_table[name]] = typecasted_attribute_value(name)
end
attrs
If you just want the array of attributes, then you could do the above and combine it with Fruit.unscoped to get a new Arel instance. There'd be nothing specific in this Arel instance about it being for `create`, i.e. `insert` in SQL. At this point you could jump over to Arel and build a new InsertManager instance I suppose:
[https://github.com/rails/arel/blob/master/lib/arel/crud.rb#L41](https://github.com/rails/arel/blob/master/lib/arel/crud.rb#L41) => [https://github.com/rails/arel/blob/master/lib/arel/insert_manager.rb](https://github.com/rails/arel/blob/master/lib/arel/insert_manager.rb)
Of course, at this point, the discussion would no longer be within the scope of rails-core, assuming no one has interest in putting this into Rails core.
-- Steve Schwartz
OK – that’s an avenue for further research. My suggestion is starting to seem like less of a good idea the more I think about it, however.
Perhaps, what’s really needed is simply more & better Arel documentation and usage examples (without sticking in lots of literal SQL bits that’ll break when table aliasing occurs). If it were easier to figure out how to do things directly in Arel, there would be little reason to use AR semantics to build Arel. I’m sure I don’t need any Rails Core group consensus to start working on more useful Arel docs.