-
Notifications
You must be signed in to change notification settings - Fork 23
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
Default array value is double-quoted/escaped #57
Comments
Hi @manuelmeurer, thanks for taking the time to report an issue! I'll take a further look into this soon. For reference, what database/adapter are you using? |
Postgres 15. Thanks for taking a look! It has something to do with
|
Could you share what the line used to described that field in This is what I'm using while debugging and wanted to double check it matches: # schema.rb
create_table "test_cases", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "default_string_array", default: ["something"], array: true
end # test_case.rb
class TestCase < ApplicationRecord
attribute :default_string_array, default: %w(newsletter)
end |
The default is set to # migration
create_table :mytable do |t|
t.text :notifications, array: true, default: [], null: false
end
# schema
create_table "mytable", force: :cascade do |t|
t.text "notifications", default: [], null: false, array: true
end
# model
attribute :notifications, default: %w(newsletter) Another questions is whether annotate should show the default as |
Not sure if you saw the tag in the PR but if you have the time and are able to test the branch, I'd be happy to merge it in after.
This is a good question. The way it's currently implemented is that it reads the value for a specific column from the This poses an interesting scenario, where if someone changes the default option in the [1] I did a quick test in a dummy Rails postgres app. # schema.rb
create_table "test_cases", force: :cascade do |t|
t.string "default_string_array", default: ['foo'], array: true
end # bin/rails c
[1] pry(main)> cols = TestCase.columns; col = cols.last
=> #<ActiveRecord::ConnectionAdapters::PostgreSQL::Column:0x000000010e67dc48
@collation=nil,
@comment=nil,
@default="{}",
@default_function=nil,
@generated="",
@name="default_string_array",
@null=true,
@serial=nil,
@sql_type_metadata=
#<ActiveRecord::ConnectionAdapters::SqlTypeMetadata:0x000000010e67df40
@limit=nil,
@precision=nil,
@scale=nil,
@sql_type="character varying[]",
@type=:string>>
[2] pry(main)> col.default
=> "{}" |
Thanks for the explanation!
What do you mean by this? I think the annotations should be on a DB level only, i.e. read from schema.rb (or structure.sql). I'll try to test the changes in the branch soon! |
Currently, annotations capture the default(s) from the database and application. What I mean by stale is that, a non-db change (such as changing the For example: # I have a model with a column that looks like this:
# In schema.rb
create_table "test_cases", force: :cascade do |t|
t.string "default_string_array", default: ["something"], array: true
end
# In the model file
# == Schema Information
#
# Table name: test_cases
#
# notifications :string default(["newsletter"]), is an Array
# ...
class TestCase < ApplicationRecord
attribute :default_string_array, default: %w(newsletter)
end There's a separate discussion to be had for "annotations should be on a DB level only, i.e. read from schema.rb (or structure.sql)". Notice the annotation uses the default from the # In the model file
# == Schema Information
#
# Table name: test_cases
#
# notifications :string default(["newsletter"]), is an Array
# ...
class TestCase < ApplicationRecord
attribute :default_string_array, default: %w(another_value) # <= the default was changed
end Without re-running annotaterb, notice the annotation will show |
This is interesting and worth discussing. Historically, I think the old annotate gem and annotaterb rely on Rails/ActiveRecord for default values. How the logic works:
This happens in I can do a spike and see if it's possible to see what are the database defaults, and if they differ, to have the option to annotate them instead of what I'll call "functional" defaults. Thoughts? |
Hmm, my personal expectation would be that only the DB defaults are taken into account. |
This makes sense. Two thoughts,
For example, a schema looks like it could provide the same default behavior you're getting with the attributes api: # schema.rb
create_table "test_cases", force: :cascade do |t|
...
t.string "default_string_array", default: ['hello'], array: true
...
end |
|
The Postgres adapter supports `array: true` for various column types [1]. In #57, it was shown that annotaterb adds escaped string values. [1] https://guides.rubyonrails.org/active_record_postgresql.html#array
Got it, that's all understandable. I think the goal of this gem should be to improve the developer experience working in Rails codebases so I'd be happy to support "db level" annotations, but doesn't seem feasible at the moment. Thanks for your help testing and I'll publish the new gem version with the fix in the next few days. |
Closing this as it should be resolved v4.4.1, which I just pushed to Rubygems. Feel free to open if the issue still exists. |
Awesome, thanks for your work on this, @drwl! 🙏 |
When I set the default value for an array text column via the Attributes API, the annotate output is double-quoted (or quoted and escaped?).
generates
Commands
Version
The text was updated successfully, but these errors were encountered: