-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use an enum as a column type #2
Comments
...and make sure it works in validations as per SchemaPlus/schema_validations#10 |
If anyone else encountered SchemaPlus/schema_plus#181, I went around the error by setting |
@ippeiukai http://apidock.com/rails/ActiveRecord/Base/schema_format/class As such, that will not work for Rails 4+. |
@saghaulor I think the |
@ippeiukai It looks like it's still in the source, but it's been moved to lib/activerecord/core.rb from lib/activerecord/base.rb. However, it doesn't seem to be working. I guess I'll continue to dig around until I find a solution. EDIT: |
@ippeiukai I'm attempting to follow your suggestion as I'm having the same problem. Where do you put that line? (Using Rails 4.2) |
@ksteensma you add it to config/application.rb |
@saghaulor tried that....I'm still getting an error. This is my migration:
` Getting this error: Any help would be most appreciated! |
@ksteensma you have to do a structure dump, not a schema dump. Rails doesn't support dumping schema for db specific datatypes. Please use Also, your migration isn't utilizing the built in functions of the gem. Namely, use |
@saghaulor Thanks for the help. I didn't know about |
You're commenting on the schema_plus_enums gem. I assumed that you're using
|
Makes perfect sense. :) |
I have set the The work around I found is to simply apply it as a separate If it was possible to do this while retaining the |
Thanks for the discussion, all. Unfortunately I don't have time to work on this, but I'd be happy to accept PRs. It might not be super-hard to add another middleware module to the Dumper middleware, to check for enum-typed columns, and replace the inline |
So if I understand correctly, currently the only way to @ronen I would be willing to work on this if it means being able to generate something that's |
@pik that's roughly it, but here's the detailed version If you use an enum column in a table (we're talking postgresql here of couse), rails can't dump it as ruby since rails doesn't recognize the enum column type. So if you're using enums in a table you need to dump as sql. That's all independent of schema_plus_enums. This gem is currently only minimally useful: it defines
If you're willing to work on this (minimally or more) that'd be great! I'm happy to answer any questions you may have, but don't have time for serious work on it myself. (And if you do get this gem more up to speed I'd be happy to give you ownership of it if you want!) |
re: defining enum columns in a migration,
def change
reversible do |direction|
direction.up do
create_enum :grade_letter, *%w[A+ A A- B+ B B- C+ C C- D+ D D- F]
end
direction.down do
drop_enum :grade_letter
end
end
create_table :course_grades do |t|
t.references :student, null: false
t.references :course, null: false
t.column :grade, :grade_letter, null: false
end
end |
Oops yeah have been writing too much coffeescript lately : ) But this could work: t.enum.grade_letter :grade, ... where Though if |
Hello, so I've started looking into this - I'm still familiarizing myself with schema_plus_core and the migration components of AR, so please correct me where I may be off. The specification for adding an enum - with something like:
Seems like it can be achieved quite readily with the current schema_plus_core/schema_monkey callback structure e.g. (in a
On the other-hand correct schema-dumping does not seem very nice or easy implementable from my understanding. The schema-dumper calls the super method which does all of the lifting https://github.com/SchemaPlus/schema_plus_core/blob/master/lib%2Fschema_plus%2Fcore%2Factive_record%2Fschema_dumper.rb#L50 and the super method does not return a partial dump of a table, but raises for the entire table (otherwise we could simply specify the rest of the columns additionally I think if an error existed along side valid parsed table structure). Looking at AR the entire table dump block is one single begin/rescue: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/schema_dumper.rb#L111 which will trigger here: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/schema_dumper.rb#L148 Valid types are determined here: @ronen would be great to have your advice on how you think we might do this without actively monkey-patching AR or the AR postgresql adapter and making such patching fit nicely into into the current schema_monkey/schema_core exposed API (it does not look like currently there is anything that can accomplish this - but I may be missing something). |
@pik thanks for looking into this! (And sorry for the long delay. I haven't had a moment to spare in real life for the past month or so, just now having one or two moments and trying to catch up on github issues.) You tracked down (thanks!) that the error is triggered at https://github.com/rails/rails/blob/master/activerecord/lib/active_record/schema_dumper.rb#L148, when @connection.valid_type?(column.type) returns false. So it seems like what's necessary is to arrange that One way to do this would be as you point out, to patch the AR postgresql adapter. This gem already has a module that gets mixed in to the adapter; so all that would be needed would be to add to def valid_enum?(type)
enums.include? type
end
def valid_type?(type)
super || valid_enum?(type)
end I'd probably try that first, and then do whatever else might be needed after that to get dumping working. (I don't know whether that would be it or whether more things would then fail farther down the line, which would need fixing.) But as you sense, it's against the spirit of schema_plus to patch existing methods of AR... except in schema_plus_core. So once dumping is working using the above, I'd go add a new middleware stack to schema_plus_core that would wrap around module SchemaPlus::Enums
module Middleware
module Postgresql
module Schema
module ValidTypeP
def after(env)
env.result ||= env.connection.valid_enum? env.type
end
end
end
end
end Defining the middleware stack in schema_plus_core will be reasonably straightforward, just pattern matching on the existing stack definitions. (Trickiest thing I think will be to just be sure to define that stack so that it'll work for all adapters, even though in this case we'll only use it for postgresql.) Does all that seem reasonable? |
Hey, any update? I tried what @kellyarwine did, found it on https://naturaily.com/blog/ruby-on-rails-enum |
The solution to change the schema dump to :sql for some reason is not acceptable for us, so I had to work out some magic to dump the schema.rb file with the extra stuff. But this will make your schema not runable by other adapters. Basically I found the place where the SchemaDumper dump all tables, it is here, follow this function, you should see how every table is dumped. If you make a file in # postgres_enum_dumper.rb
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter
NATIVE_DATABASE_TYPES.merge!(
enum: { name: 'character varying' },
)
end
class SchemaDumper
def dump(stream)
header(stream)
# Dump created enums
extensions(stream)
tables(stream)
trailer(stream)
stream
end
end
end This may be temporary as you are actually replacing the private functions and they are subject to change. But it is the best solution for us. |
Should be able to use an enum as a column type, via
or even maybe something like
See, e.g., discussion at https://coderwall.com/p/azi3ka
[Issue pulled over from SchemaPlus/schema_plus#174 and SchemaPlus/schema_plus#181]
The text was updated successfully, but these errors were encountered: