So proposal would be in activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
You would add :column_options support, like:
def create_table(table_name, options = {})
td = table_definition
td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
yield td if block_given?
if options[:force] && table_exists?(table_name)
drop_table(table_name, options)
end
create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
create_sql << "#{quote_table_name(table_name)} ("
create_sql << td.to_sql
create_sql << "#{options[:column_options]}"
create_sql << ") #{options[:options]}"
execute create_sql
td.indexes.each_pair { |c,o| add_index table_name, c, o }
end
Not sure if would want to add similar option in other places to be consistent, though...
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
OF type_name [ (
{ column_name WITH OPTIONS [ column_constraint [ ... ] ]
| table_constraint }
[, ... ]
) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace ]
where column_constraint is:
[ CONSTRAINT constraint_name ]
{ NOT NULL |
NULL |
CHECK ( expression ) |
DEFAULT default_expr |
UNIQUE index_parameters |
PRIMARY KEY index_parameters |
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
and table_constraint is:
[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) |
UNIQUE ( column_name [, ... ] ) index_parameters |
PRIMARY KEY ( column_name [, ... ] ) index_parameters |
EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
--To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/6nltHuNceFMJ.
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 rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Rodrigo,
We're using postgres with structure.sql and a legacy DB that has plenty of constraints (fkey, unique) and in the Rails app using that schema for new migrations we're using foreigner ( https://github.com/matthuhiggins/foreigner ) to add new fkeys, and iirc using add_index for some unique constraints (a la http://stackoverflow.com/a/3370333/178651 ). I've read mixed things about using deferrable for everything, but it might be appropriate in some apps.
AR supports using execute to add/remove constraints, etc. also, and foreigner supports deferrable via specifying new constraints like:
add_foreign_key(:employees, :companies, :options => 'deferrable')
Rails create_table I think may be the only place that doesn't allow custom SQL for constraint definition, and I got schooled on that yesterday when trying to allow a spot for custom SQL within the parenths of the generated SQL for create table. :)
I agree that Rails could be more constraint-friendly, but I think you can accomplish what you are trying to do with what is there?
On Thursday, November 29, 2012 5:59:11 AM UTC-5, Rodrigo Rosenfeld Rosas wrote:I think I'm late at the party and lost a lot happening here yesterday...
At least it is good to know what core considers a good fit or not for AR Migrations. Since constraints are a fundamental piece in my projects I get the warning "you should avoid AR at all, including AR migrations". Currently it is not a big deal for me as I don't plan to support any other database vendor than PG so I can keep using "execute" in my migrations but I thought that maybe some OSS projects could benefit from some built-in support in AR migrations when using a popular plugin like this one:
https://github.com/collectiveidea/awesome_nested_set/blob/master/lib/awesome_nested_set/awesome_nested_set.rb#L655
I don't really believe the method above will always work in PG, for example, if some OSS project has created an index like:
add_index :some_table, [:parent_id, :lft], unique: true
add_index :some_table, [:parent_id, :rgt], unique: true
The Rails community still doesn't seem to be mature enough yet with regards to database constraints, which is unfortunate, so I believe most people using awesome_nested_set (I never used, just took some popular gem as an example) don't have the indices above in their migration. And if it happens for an OSS project to have an unique index like above it is likely that it won't always work in PG unless the OSS project uses a custom "add_unique_index" that would be portable among database vendors to include the deferrable constraint instead for databases like PG.
I just suggested that unique constraints/indices should be deferrable by default to avoid the problem above, which seems to be a very common use-case. Otherwise the message that comes to me is "if you're not doing MySql, get away from AR. we just pretend to support PG, but if you need first-class support, you should be really considering a more robust ORM, like Sequel".
Em 28-11-2012 17:15, Rafael Mendonça França escreveu:I don't think this is a good fit for the core.
You are able to use SQL statements inside your migrations, so we already support this.
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/YhSw7VXH1kEJ.
add_foreign_key(:employees, :companies, :options => 'deferrable')
What is the effect of the code above in such scenario if a user wants to run the code on MySql or MS SQL Server?
case ActiveRecord::Base.connection.adapter_name
when 'PostgreSQL', 'Oracle'
add_foreign_key(:employees, :companies, :options => 'deferrable')
when 'MySQL'end
else
raise "Database adapter not supported. Please file issue at (url to your github repo issues)"
Em 29-11-2012 09:21, Gary Weaver escreveu:
...
If the Rails community can't convince itself about the importance of basic things in ACID databases like transactions, foreign keys and other constraints than I think I'm out of luck with regards to deferrable constraints... :( (yes, when I talk about transactions I mean the huge amount of Rails applications out there running MySql with MyISAM engine, that used to be the default one until recently in 5.5 when the InnoDB is now the default one).
--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
I won't ever write a patch before getting it accepted first. I've done it once after some previous discussion and after the issue became totally abandoned with no feedback I decided that I wouldn't ever do it again. Too much effort to code to get it rejected or ignored later.
And, just for record, I don't like Cucumber ;)
We can't accept a feature without know what are the impacts in the codebase.
This is valid for everyone, either the core members.
I can say that I want this feature and accept it, but nothing stops the core members to revert it. And don't expect me to defend your feature, since you should be the interested.
Would be more waste of time if we accept it now and, when you come up with the code, we rejected it because it add more complexity in the framework that we want.
Also, what is the difference of writing 10 huge emails and get the feature reject?
I think is the same. With working code you have more chances. And, as I said in my last email, either if we don't accept, you will have working code that solves your problem.
If you don't want to scratch your itch and provide a patch, I'm sorry, but don't expect we to accept.
And, just for record, I don't like Cucumber ;)
My perception is that although this list is called rails-core it seems core members don't actually read it. Otherwise it would be easy to achieve a consensus about approving this feature or not before implementing it.
- a core member wants a feature
- he writes the change, commit it and push it
- another core member don't like the change and revert the commit
- some other core member liked the change and revert the commit that has been reverted
How is that sane? In what point prior discussion became invaluable? This is not how I manage my teams/softwares and I'm pretty sure this is not how most projects out there work.
If it happens that you don't like my change, I'd expect you to show me how you think such feature should be implemented instead. But it wouldn't be rejected. At some point the implementation would conform to what the core-team expect it to look like.
No, I won't. First, I don't have a problem. I use PG and I have no plans to support other DB vendor. But it crossed my mind the idea that maybe some open-source software could benefit from a common API to add support for deferrable unique constraints because some very common use cases (ordered tree/list) would require that and just asked here if there was such an interest in that feature.
My perception is that although this list is called rails-core it seems core members don't actually read it. Otherwise it would be easy to achieve a consensus about approving this feature or not before implementing it.
Wrong, they read. I'm a core member.
- a core member wants a feature
- he writes the change, commit it and push it
- another core member don't like the change and revert the commit
- some other core member liked the change and revert the commit that has been reverted
How is that sane? In what point prior discussion became invaluable? This is not how I manage my teams/softwares and I'm pretty sure this is not how most projects out there work.
This is right. But this is more like:
- someone want a feature- someone write the patch- the core team discuss- we accept or reject the feature- Maybe someone from the core that didn't participate from the discussion has a strong opinion about the feature, we start the discussion again and if we agree, revert.
This is how Rails works since the beginning. And I think it is working.
If it happens that you don't like my change, I'd expect you to show me how you think such feature should be implemented instead. But it wouldn't be rejected. At some point the implementation would conform to what the core-team expect it to look like.
You said everything, all pull requests that I reviewed and the core agree was merged. The discussions were not, since they are only email threads. Pull requests are the best place to discussion, we can see the implementation details and the feature overview in one place.
No, I won't. First, I don't have a problem. I use PG and I have no plans to support other DB vendor. But it crossed my mind the idea that maybe some open-source software could benefit from a common API to add support for deferrable unique constraints because some very common use cases (ordered tree/list) would require that and just asked here if there was such an interest in that feature.
Rails is not a set of guessing features. We try to extract features from real applications that we think is a good fit for the framework.
And to close this thread, I'm really sorry if the contribution experience was not good for you in the past, but you can be sure that there are a lot of people trying to make it better now.
Please, send a patch if you want, you may be surprised. ;)
So, it is not that quick either to get started contributing to Rails (it may require an hour or two just to get the tests passing).
it is likely that I won't try to contribute to Rails for many more years if the patch isn't accepted after some feedback to get it in conformance with core's taste.
So, it is not that quick either to get started contributing to Rails (it may require an hour or two just to get the tests passing).
Thanks!