GithubHelp home page GithubHelp logo

Comments (24)

diogob avatar diogob commented on June 13, 2024

It does not seem a good practice database wise. What do you mean with smoothly use store_acessor? To be quite frank, I've never tried to use store_acessor with a hstore column.

from activerecord-postgres-hstore.

sxua avatar sxua commented on June 13, 2024

store_accessor works just fine with hstore column (read-only). And about default, I mean ability to setup column like this: t.hstore :data, default: [] or something else.

from activerecord-postgres-hstore.

diogob avatar diogob commented on June 13, 2024

Do you mean t.hstore :data, default: {} ? Using an empty array instead of a hash does not seems a consistent behavior.

from activerecord-postgres-hstore.

sxua avatar sxua commented on June 13, 2024

Yeah, hash, not array.

from activerecord-postgres-hstore.

diogob avatar diogob commented on June 13, 2024

Yeah, it would be nice indeed, I'll take a look into it.

from activerecord-postgres-hstore.

amacneil avatar amacneil commented on June 13, 2024

Related to this, would it be possible for the default to always return an empty hash, rather than nil?

Currently it's hard to call things like row.data["key"], because if there are no keys it throws undefined method `[]' for nil:NilClass

Let me know if I'm missing something here :)

from activerecord-postgres-hstore.

sxua avatar sxua commented on June 13, 2024

For now you can use default value in database, adding this to your migration:
execute("ALTER TABLE your_table ALTER COLUMN data SET DEFAULT hstore(array[]::varchar[])")

from activerecord-postgres-hstore.

chrisvariety avatar chrisvariety commented on June 13, 2024

+1 this would be great to have. I am looking to be able to do

Page.new.data[:test] = 'abc123'

without it blowing up about .data being nil by default.

I tried the ALTER TABLE... but it didn't seem to work.

from activerecord-postgres-hstore.

alhafoudh avatar alhafoudh commented on June 13, 2024

+1

from activerecord-postgres-hstore.

mohangk avatar mohangk commented on June 13, 2024

+1

from activerecord-postgres-hstore.

chancancode avatar chancancode commented on June 13, 2024

@adrianmacneil I agree the ability to set a default column value in the migration would be nice to have, but I would not make that the "default" behaviour of the gem. NULL and {} are two different things.

from activerecord-postgres-hstore.

amacneil avatar amacneil commented on June 13, 2024

I'm aware NULL and {} are different things, but I don't think NULL is a very useful default (because as mentioned above it throws an exception if you try to access a key, so you would always need to test the nil case before accessing the hash). At least being able to specify the default in a migration would work around this though. But it would be nice if this gem could handle a NULL database value and still allow writing to the hash without testing for nil first.

from activerecord-postgres-hstore.

chancancode avatar chancancode commented on June 13, 2024

As I mention in #25, I see activerecord-postgres-hstore's role as library that provides lowest-level access (next to writing raw SQL) to HStore in ActiveRecord, so people could build useful stuff on top of it. It should expose all the available features that HStore exposes, and one of these features is the ability to assign NULL as the value for a key. This should take precedence over any connivence/sugar/abstraction that the gem may choose to provide (i.e. any "fix" for this "problem" should not break the ability to assign NULL to a key).

t.hstore :data, default: {} seems to be a good compromise. Or you could also do it at the active record level and initialize the value with an after_initialize callback.

from activerecord-postgres-hstore.

diogob avatar diogob commented on June 13, 2024

@chancancode I was thinking about the explicit default usage inside the migration. But sincerely I do not have the time to work on this now. If someone want to make a pull request with this behaviour though...
I'll leave the issue open.

from activerecord-postgres-hstore.

chancancode avatar chancancode commented on June 13, 2024

I'm wondering if this already works today. If you assign an empty string to the HStore column in SQL, it becomes an empty HStore. So perhaps...

t.hstore :data, default: ""

already works? I'll check later today.

from activerecord-postgres-hstore.

axsuul avatar axsuul commented on June 13, 2024

Just tried this today. Doesn't seem to give us an empty HStore

t.hstore :data, default: ""

from activerecord-postgres-hstore.

jjb avatar jjb commented on June 13, 2024

I think there are two things being discussed here:

  1. the basic ability to specify a default value in the migration, sent to the database. this is probably a non-controversial feature that would just be convenient to have in some cases (or irrelevant, depending on 2, below)
  2. how the gem represents a NULL column value (as nil, or as {}). I'll discuss this issue bellow.

Here's a problem I have, which might be (very?) common for users of this gem: I have a model Foo with an hstore column metadata. It's possible that it has no metadata at all, or many key/values. Wherever I access the metadata, I have to do ye olde @foo.metadata && @foo.metadata['my_key'] because @foo.metadata might be nil.

I would rather that in the case of a NULL metadata column, @foo.metadata returned {}. In my use case, metadata being nil has no semantic purpose.

In another use case, it might. However, even if I did have such a use case, I imagine that checking @foo.metadata.empty? would be semantically sufficient, and possibly preferable.

So maybe a good question to explore to move this forward: can anyone think of use cases where there is a semantic difference between {} and nil, so that support for both is desired?

from activerecord-postgres-hstore.

zacksiri avatar zacksiri commented on June 13, 2024

yes there is, what if i am iterating through a hash like this

my_stuff.data.each do |k, v| 
  puts "#{k}, #{v}"
end

.each fails because when initializing the hstore the data field = nil and each doesn't work with nil

for now i am doing after_initialize as a work around

from activerecord-postgres-hstore.

jjb avatar jjb commented on June 13, 2024

@zacksiri so if I understand, you would like data to be {} in that case, right?

I was asking if anyone had a case for supporting both {} and nil.

from activerecord-postgres-hstore.

zacksiri avatar zacksiri commented on June 13, 2024

@jjb yeah it makes sense to allow us to define a default option for the hstore field to an empty hash or nil to who ever wishes it to be nil

t.hstore :data, default: {}

from activerecord-postgres-hstore.

adamrobbie avatar adamrobbie commented on June 13, 2024

+1

from activerecord-postgres-hstore.

stevo avatar stevo commented on June 13, 2024

AR's extract_value_from_default method seems to ignore hstore-type defaults. This short patch deals with the issue

module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLColumn < Column
      private
      class << self
        def extract_value_from_default_with_hstore(default)
          case default
            when NilClass
              nil
            when /(^+hstore|hstore$+)/
              {}
            else
              extract_value_from_default_without_hstore(default)
          end
        end

        alias_method_chain :extract_value_from_default, :hstore
      end
    end
  end
end

obviously we could extract default key/value pairs etc... but this is the simplest solution to make SET DEFAULT hstore(array[]::varchar[]) or SET DEFAULT '' actually work with ActiveRecord...

from activerecord-postgres-hstore.

alhafoudh avatar alhafoudh commented on June 13, 2024

@stevo That fix does something nasty and is not correct. The initial hstore value leaks from somewhere randomly.

I got:

...
t.hstore :options, null: false, default: {}
...

and your code snippet in config/initializers/hstore_fix.rb

Sometimes I got hstore initial value from other test case that I used on blank test case.

[8] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new
=> #<Action id: nil, trigger_id: nil, type: nil, options: {"foo"=>"bar"}, position: 1, created_at: nil, updated_at: nil>
[9] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new
=> #<Action id: nil, trigger_id: nil, type: nil, options: {"foo"=>"bar"}, position: 1, created_at: nil, updated_at: nil>
[10] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new
=> #<Action id: nil, trigger_id: nil, type: nil, options: {"foo"=>"bar"}, position: 1, created_at: nil, updated_at: nil>
[11] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new
=> #<Action id: nil, trigger_id: nil, type: nil, options: {"foo"=>"bar"}, position: 1, created_at: nil, updated_at: nil>
[12] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new
=> #<Action id: nil, trigger_id: nil, type: nil, options: {"foo"=>"bar"}, position: 1, created_at: nil, updated_at: nil>
[13] pry(#<RSpec::Core::ExampleGroup::Nested_4::Nested_1>)> Action.new

from activerecord-postgres-hstore.

jjb avatar jjb commented on June 13, 2024

Looks like @chrisrhoden and @diogob actually added support for this a few days ago, whoo hoo!

5c2efd4

from activerecord-postgres-hstore.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.