ActiveModel::Dirty and JSON fields












3















I am using ActiveModel::Dirty to track changes made in a form. Now everything is working as I expect. With stuff like phone numbers that get dashes in them when in the form I simply format them and then the phone number will not appear in the list of .changed which is expected behavior.



However I run into an issue where I am using a jsonb field in my Profile model. So the issue is ActiveModel will list the JSONB field as being changed even though I format it specifically to match how it looked before. This is not expected behavior. What's stranger still is that another JSONB column I have does not experience this madness.



The JSONB field I'm having trouble with looks like this

store_accessor :user_details, :names, :other_field
store_accessor :bank_details, :bank_city, :bank_name

user_details and bank_details are jsonb columns.
Some things to note: names is an array, other_field is a string.
bank_city and bank_name are strings.



Can anyone shed some insight into why :user_details specifically is struggling with this issue and not the :bank_details JSON column?



I am suspecting it might be due to me using an array within the :user_details and I suspect that the comparison is being thrown off somewhere in the ActiveModel source code, but maybe I'm wrong?



Edit:
I have discovered it is definitely because I am using an array for :names. I changed it to be a string and it stopped thinking that the JSON column had been changed. Going to dig into the ActiveModel source code to see if I can find a reason why.



Edit #2:
For some reason I thought I solved the issue by doing nothing but I'm a dummy and realized that I had removed something in the form. So this issue still hasn't been solved for me. Any insight would be amazing. I can't figure out from looking into the ActiveModel::Dirty source code why this is happening. I'm not entirely sure where to look. Going to slap in byebugs to see if that helps.



Edit #3:
Steps to repeat this issue



Create a rails Model with a JSONB column.
Set store accessors you just need one to do this.
Have it default using either a validator or formatter to be an empty array.
Give your model the ActiveModel::Dirty include.
Run the rails console.
run the following commands.
Imagine that user_details is the JSONB column and its store accessor is names.



  a = Profile.user_details
a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
a.changed # This will show that user_details has changed which is correct
a.names =
a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.









share|improve this question





























    3















    I am using ActiveModel::Dirty to track changes made in a form. Now everything is working as I expect. With stuff like phone numbers that get dashes in them when in the form I simply format them and then the phone number will not appear in the list of .changed which is expected behavior.



    However I run into an issue where I am using a jsonb field in my Profile model. So the issue is ActiveModel will list the JSONB field as being changed even though I format it specifically to match how it looked before. This is not expected behavior. What's stranger still is that another JSONB column I have does not experience this madness.



    The JSONB field I'm having trouble with looks like this

    store_accessor :user_details, :names, :other_field
    store_accessor :bank_details, :bank_city, :bank_name

    user_details and bank_details are jsonb columns.
    Some things to note: names is an array, other_field is a string.
    bank_city and bank_name are strings.



    Can anyone shed some insight into why :user_details specifically is struggling with this issue and not the :bank_details JSON column?



    I am suspecting it might be due to me using an array within the :user_details and I suspect that the comparison is being thrown off somewhere in the ActiveModel source code, but maybe I'm wrong?



    Edit:
    I have discovered it is definitely because I am using an array for :names. I changed it to be a string and it stopped thinking that the JSON column had been changed. Going to dig into the ActiveModel source code to see if I can find a reason why.



    Edit #2:
    For some reason I thought I solved the issue by doing nothing but I'm a dummy and realized that I had removed something in the form. So this issue still hasn't been solved for me. Any insight would be amazing. I can't figure out from looking into the ActiveModel::Dirty source code why this is happening. I'm not entirely sure where to look. Going to slap in byebugs to see if that helps.



    Edit #3:
    Steps to repeat this issue



    Create a rails Model with a JSONB column.
    Set store accessors you just need one to do this.
    Have it default using either a validator or formatter to be an empty array.
    Give your model the ActiveModel::Dirty include.
    Run the rails console.
    run the following commands.
    Imagine that user_details is the JSONB column and its store accessor is names.



      a = Profile.user_details
    a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
    a.changed # This will show that user_details has changed which is correct
    a.names =
    a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.









    share|improve this question



























      3












      3








      3


      1






      I am using ActiveModel::Dirty to track changes made in a form. Now everything is working as I expect. With stuff like phone numbers that get dashes in them when in the form I simply format them and then the phone number will not appear in the list of .changed which is expected behavior.



      However I run into an issue where I am using a jsonb field in my Profile model. So the issue is ActiveModel will list the JSONB field as being changed even though I format it specifically to match how it looked before. This is not expected behavior. What's stranger still is that another JSONB column I have does not experience this madness.



      The JSONB field I'm having trouble with looks like this

      store_accessor :user_details, :names, :other_field
      store_accessor :bank_details, :bank_city, :bank_name

      user_details and bank_details are jsonb columns.
      Some things to note: names is an array, other_field is a string.
      bank_city and bank_name are strings.



      Can anyone shed some insight into why :user_details specifically is struggling with this issue and not the :bank_details JSON column?



      I am suspecting it might be due to me using an array within the :user_details and I suspect that the comparison is being thrown off somewhere in the ActiveModel source code, but maybe I'm wrong?



      Edit:
      I have discovered it is definitely because I am using an array for :names. I changed it to be a string and it stopped thinking that the JSON column had been changed. Going to dig into the ActiveModel source code to see if I can find a reason why.



      Edit #2:
      For some reason I thought I solved the issue by doing nothing but I'm a dummy and realized that I had removed something in the form. So this issue still hasn't been solved for me. Any insight would be amazing. I can't figure out from looking into the ActiveModel::Dirty source code why this is happening. I'm not entirely sure where to look. Going to slap in byebugs to see if that helps.



      Edit #3:
      Steps to repeat this issue



      Create a rails Model with a JSONB column.
      Set store accessors you just need one to do this.
      Have it default using either a validator or formatter to be an empty array.
      Give your model the ActiveModel::Dirty include.
      Run the rails console.
      run the following commands.
      Imagine that user_details is the JSONB column and its store accessor is names.



        a = Profile.user_details
      a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
      a.changed # This will show that user_details has changed which is correct
      a.names =
      a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.









      share|improve this question
















      I am using ActiveModel::Dirty to track changes made in a form. Now everything is working as I expect. With stuff like phone numbers that get dashes in them when in the form I simply format them and then the phone number will not appear in the list of .changed which is expected behavior.



      However I run into an issue where I am using a jsonb field in my Profile model. So the issue is ActiveModel will list the JSONB field as being changed even though I format it specifically to match how it looked before. This is not expected behavior. What's stranger still is that another JSONB column I have does not experience this madness.



      The JSONB field I'm having trouble with looks like this

      store_accessor :user_details, :names, :other_field
      store_accessor :bank_details, :bank_city, :bank_name

      user_details and bank_details are jsonb columns.
      Some things to note: names is an array, other_field is a string.
      bank_city and bank_name are strings.



      Can anyone shed some insight into why :user_details specifically is struggling with this issue and not the :bank_details JSON column?



      I am suspecting it might be due to me using an array within the :user_details and I suspect that the comparison is being thrown off somewhere in the ActiveModel source code, but maybe I'm wrong?



      Edit:
      I have discovered it is definitely because I am using an array for :names. I changed it to be a string and it stopped thinking that the JSON column had been changed. Going to dig into the ActiveModel source code to see if I can find a reason why.



      Edit #2:
      For some reason I thought I solved the issue by doing nothing but I'm a dummy and realized that I had removed something in the form. So this issue still hasn't been solved for me. Any insight would be amazing. I can't figure out from looking into the ActiveModel::Dirty source code why this is happening. I'm not entirely sure where to look. Going to slap in byebugs to see if that helps.



      Edit #3:
      Steps to repeat this issue



      Create a rails Model with a JSONB column.
      Set store accessors you just need one to do this.
      Have it default using either a validator or formatter to be an empty array.
      Give your model the ActiveModel::Dirty include.
      Run the rails console.
      run the following commands.
      Imagine that user_details is the JSONB column and its store accessor is names.



        a = Profile.user_details
      a.user_details = { "names" => [{"first_name" => "", "last_name" => "" }] } # This is to replicate what it would look like in a form when a user is submitting a blank entry.
      a.changed # This will show that user_details has changed which is correct
      a.names =
      a.changed # This will still show that user_details has changed even though it has been set back to its initial state of an empty array. This would work if it was a string field instead of an array.






      ruby-on-rails ruby activemodel






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 27 '18 at 15:54







      Gabriel

















      asked Nov 26 '18 at 22:34









      GabrielGabriel

      311213




      311213
























          1 Answer
          1






          active

          oldest

          votes


















          0














          After opening an issue on the Rails Github I got a response https://github.com/rails/rails/issues/34537#issuecomment-442265161



          The change is forced through the attributes for json, jsonb, hstore, and serialized attribute types is what I was told. Source code here: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181



          The reason I came across this is something I'm no longer trying to attempt as the project I'm working on isn't going to be using ActiveModel::Dirty and isn't going to try tracking the changes the way I was attempting to do it.



          So any future generations that come across this issue good luck and feel free to go into that github issue and complain about this not working.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53490150%2factivemodeldirty-and-json-fields%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            After opening an issue on the Rails Github I got a response https://github.com/rails/rails/issues/34537#issuecomment-442265161



            The change is forced through the attributes for json, jsonb, hstore, and serialized attribute types is what I was told. Source code here: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181



            The reason I came across this is something I'm no longer trying to attempt as the project I'm working on isn't going to be using ActiveModel::Dirty and isn't going to try tracking the changes the way I was attempting to do it.



            So any future generations that come across this issue good luck and feel free to go into that github issue and complain about this not working.






            share|improve this answer






























              0














              After opening an issue on the Rails Github I got a response https://github.com/rails/rails/issues/34537#issuecomment-442265161



              The change is forced through the attributes for json, jsonb, hstore, and serialized attribute types is what I was told. Source code here: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181



              The reason I came across this is something I'm no longer trying to attempt as the project I'm working on isn't going to be using ActiveModel::Dirty and isn't going to try tracking the changes the way I was attempting to do it.



              So any future generations that come across this issue good luck and feel free to go into that github issue and complain about this not working.






              share|improve this answer




























                0












                0








                0







                After opening an issue on the Rails Github I got a response https://github.com/rails/rails/issues/34537#issuecomment-442265161



                The change is forced through the attributes for json, jsonb, hstore, and serialized attribute types is what I was told. Source code here: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181



                The reason I came across this is something I'm no longer trying to attempt as the project I'm working on isn't going to be using ActiveModel::Dirty and isn't going to try tracking the changes the way I was attempting to do it.



                So any future generations that come across this issue good luck and feel free to go into that github issue and complain about this not working.






                share|improve this answer















                After opening an issue on the Rails Github I got a response https://github.com/rails/rails/issues/34537#issuecomment-442265161



                The change is forced through the attributes for json, jsonb, hstore, and serialized attribute types is what I was told. Source code here: https://github.com/rails/rails/blob/06ab7b27ea1c1ab357085439abacdb464f6742bf/activerecord/lib/active_record/store.rb#L181



                The reason I came across this is something I'm no longer trying to attempt as the project I'm working on isn't going to be using ActiveModel::Dirty and isn't going to try tracking the changes the way I was attempting to do it.



                So any future generations that come across this issue good luck and feel free to go into that github issue and complain about this not working.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 28 '18 at 21:35

























                answered Nov 28 '18 at 16:22









                GabrielGabriel

                311213




                311213
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53490150%2factivemodeldirty-and-json-fields%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                    Calculate evaluation metrics using cross_val_predict sklearn

                    Insert data from modal to MySQL (multiple modal on website)