Skip to content

Bug: JSONDeserialize module not handling #202

Description

@dukenguyenxyz

Whilst JSONDeserialize modules with the associated .from_json, .create_from_json, and .set_from_json work with most models, it seems to not work on models that declare the column_name field.

The following Post model

class Post
include Clear::Model
self.table = "model_posts"
column id : Int32, primary: true, presence: false
column title : String
column tags : Array(String), presence: false
column flags : Array(Int64), presence: false, column_name: "flags_other_column_name"
column content : String, presence: false
column published : Bool, presence: false
scope("published") { where published: true }
def validate
ensure_than(title, "is not empty", &.size.>(0))
end
has_many post_tags : PostTag, foreign_key: "post_id"
has_many tag_relations : Tag, through: :post_tags, relation: :tag
belongs_to user : User, foreign_key_type: Int32
belongs_to category : Category?, foreign_key_type: Int32
end

with the following column

column flags : Array(Int64), presence: false, column_name: "flags_other_column_name"

fails with the following spec

    it "can create a new model instance with a column with column_name field" do
      temporary do
        reinit_example_models

        u = User.create!({first_name: "John"})
        p = Post.create_from_json({title: "A post", user_id: u.id}.to_json)
        p.title.should eq("A post")
        p.user_id.should eq(u.id)
      end
    end

The full stackstrace is as below

error in line 19
Error: while requiring "./spec/model/model_spec.cr"


In spec/model/model_spec.cr:644:7

 644 | temporary do
       ^--------
Error: instantiating 'temporary()'


In spec/spec_helper.cr:54:14

 54 | Clear::SQL.with_savepoint do
                 ^-------------
Error: instantiating 'Clear::SQL:Module#with_savepoint()'


In src/clear/sql/transaction.cr:114:5

 114 | transaction do |cnx|
       ^----------
Error: instantiating 'transaction()'


In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'


In src/clear/sql/transaction.cr:47:32

 47 | Clear::SQL::ConnectionPool.with_connection(connection) do |cnx|
                                 ^--------------
Error: instantiating 'Clear::SQL::ConnectionPool.class#with_connection(String)'


In src/clear/sql/transaction.cr:114:5

 114 | transaction do |cnx|
       ^----------
Error: instantiating 'transaction()'


In spec/spec_helper.cr:54:14

 54 | Clear::SQL.with_savepoint do
                 ^-------------
Error: instantiating 'Clear::SQL:Module#with_savepoint()'


In spec/model/model_spec.cr:644:7

 644 | temporary do
       ^--------
Error: instantiating 'temporary()'


In spec/model/model_spec.cr:648:18

 648 | p = Post.create_from_json({title: "A post", user_id: u.id}.to_json)
                ^---------------
Error: instantiating 'Post.class#create_from_json(String)'


There was a problem expanding macro 'finished'

Called macro defined in macro 'included'

 7 | macro finished

Which expanded to:

 > 1 |         columns_to_instance_vars
 > 2 |       
Error: expanding macro


There was a problem expanding macro 'columns_to_instance_vars'

Called macro defined in src/clear/model/json_deserialize.cr:19:1

 19 | macro columns_to_instance_vars

Which expanded to:

 >   1 |   # :nodoc:
 >   2 |   struct Assigner
 >   3 |     include JSON::Serializable
 >   4 | 
 >   5 |     
 >   6 |       @[JSON::Field(presence: true)]
 >   7 |       getter id : Int32  | Nil 
 >   8 |       @[JSON::Field(ignore: true)]
 >   9 |       getter? id_present : Bool
 >  10 |     
 >  11 |       @[JSON::Field(presence: true)]
 >  12 |       getter title : String  | Nil 
 >  13 |       @[JSON::Field(ignore: true)]
 >  14 |       getter? title_present : Bool
 >  15 |     
 >  16 |       @[JSON::Field(presence: true)]
 >  17 |       getter tags : Array(String)  | Nil 
 >  18 |       @[JSON::Field(ignore: true)]
 >  19 |       getter? tags_present : Bool
 >  20 |     
 >  21 |       @[JSON::Field(presence: true)]
 >  22 |       getter flags_other_column_name : Array(Int64)  | Nil 
 >  23 |       @[JSON::Field(ignore: true)]
 >  24 |       getter? flags_other_column_name_present : Bool
 >  25 |     
 >  26 |       @[JSON::Field(presence: true)]
 >  27 |       getter content : String  | Nil 
 >  28 |       @[JSON::Field(ignore: true)]
 >  29 |       getter? content_present : Bool
 >  30 |     
 >  31 |       @[JSON::Field(presence: true)]
 >  32 |       getter published : Bool  | Nil 
 >  33 |       @[JSON::Field(ignore: true)]
 >  34 |       getter? published_present : Bool
 >  35 |     
 >  36 |       @[JSON::Field(presence: true)]
 >  37 |       getter user_id : Int32  | Nil 
 >  38 |       @[JSON::Field(ignore: true)]
 >  39 |       getter? user_id_present : Bool
 >  40 |     
 >  41 |       @[JSON::Field(presence: true)]
 >  42 |       getter category_id : Int32 | ::Nil 
 >  43 |       @[JSON::Field(ignore: true)]
 >  44 |       getter? category_id_present : Bool
 >  45 |     
 >  46 | 
 >  47 |     # Create a new empty model and fill the columns with object's instance variables
 >  48 |     # Trusted flag set to true will allow mass assignment without protection
 >  49 |     def create(trusted : Bool)
 >  50 |       assign_columns(Post.new, trusted)
 >  51 |     end
 >  52 | 
 >  53 |     # Update the inputted model and assign the columns with object's instance variables
 >  54 |     # Trusted flag set to true will allow mass assignment without protection
 >  55 |     def update(model, trusted : Bool)
 >  56 |       assign_columns(model, trusted)
 >  57 |     end
 >  58 | 
 >  59 |     macro finished
 >  60 |       # Assign properties to the model inputted with object's instance variables
 >  61 |       # Trusted flag set to true will allow mass assignment without protection
 >  62 |       protected def assign_columns(model, trusted : Bool)
 >  63 |         
 >  64 |           if (true || trusted) && self.id_present?
 >  65 |             __temp_121 = self.id
 >  66 |             
 >  67 |               model.id = __temp_121 unless __temp_121.nil?
 >  68 |             
 >  69 |           end
 >  70 |         
 >  71 |           if (true || trusted) && self.title_present?
 >  72 |             __temp_121 = self.title
 >  73 |             
 >  74 |               model.title = __temp_121 unless __temp_121.nil?
 >  75 |             
 >  76 |           end
 >  77 |         
 >  78 |           if (true || trusted) && self.tags_present?
 >  79 |             __temp_121 = self.tags
 >  80 |             
 >  81 |               model.tags = __temp_121 unless __temp_121.nil?
 >  82 |             
 >  83 |           end
 >  84 |         
 >  85 |           if (true || trusted) && self.flags_other_column_name_present?
 >  86 |             __temp_121 = self.flags_other_column_name
 >  87 |             
 >  88 |               model.flags_other_column_name = __temp_121 unless __temp_121.nil?
 >  89 |             
 >  90 |           end
 >  91 |         
 >  92 |           if (true || trusted) && self.content_present?
 >  93 |             __temp_121 = self.content
 >  94 |             
 >  95 |               model.content = __temp_121 unless __temp_121.nil?
 >  96 |             
 >  97 |           end
 >  98 |         
 >  99 |           if (true || trusted) && self.published_present?
 > 100 |             __temp_121 = self.published
 > 101 |             
 > 102 |               model.published = __temp_121 unless __temp_121.nil?
 > 103 |             
 > 104 |           end
 > 105 |         
 > 106 |           if (true || trusted) && self.user_id_present?
 > 107 |             __temp_121 = self.user_id
 > 108 |             
 > 109 |               model.user_id = __temp_121 unless __temp_121.nil?
 > 110 |             
 > 111 |           end
 > 112 |         
 > 113 |           if (true || trusted) && self.category_id_present?
 > 114 |             __temp_121 = self.category_id
 > 115 |             
 > 116 |               model.category_id = __temp_121
 > 117 |             
 > 118 |           end
 > 119 |         
 > 120 | 
 > 121 |         model
 > 122 |       end
 > 123 |     end
 > 124 |   end
 > 125 | 
 > 126 |   # Create a new empty model and fill the columns from json. Returns the new model
 > 127 |   #
 > 128 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 129 |   def self.from_json(string_or_io : String | IO, trusted : Bool = false)
 > 130 |     Assigner.from_json(string_or_io).create(trusted)
 > 131 |   end
 > 132 | 
 > 133 |   # Create a new model from json and save it. Returns the model.
 > 134 |   #
 > 135 |   # The model may not be saved due to validation failure;
 > 136 |   # check the returned model `errors?` and `persisted?` flags.
 > 137 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 138 |   def self.create_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 139 |     mdl = self.from_json(string_or_io, trusted)
 > 140 |     mdl.save
 > 141 |     mdl
 > 142 |   end
 > 143 | 
 > 144 |   # Create a new model from json and save it. Returns the model.
 > 145 |   #
 > 146 |   # Returns the newly inserted model
 > 147 |   # Raises an exception if validation failed during the saving process.
 > 148 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 149 |   def self.create_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 150 |     self.from_json(string_or_io, trusted).save!
 > 151 |   end
 > 152 | 
 > 153 |   # Set the fields from json passed as argument
 > 154 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 155 |   def set_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 156 |     Assigner.from_json(string_or_io).update(self, trusted)
 > 157 |   end
 > 158 | 
 > 159 |   # Set the fields from json passed as argument and call `save` on the object
 > 160 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 161 |   def update_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 162 |     mdl = set_from_json(string_or_io, trusted)
 > 163 |     mdl.save
 > 164 |     mdl
 > 165 |   end
 > 166 | 
 > 167 |   # Set the fields from json passed as argument and call `save!` on the object
 > 168 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 169 |   def update_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 170 |     set_from_json(string_or_io, trusted).save!
 > 171 |   end
Error: instantiating 'Post.class#from_json(String, Bool)'


There was a problem expanding macro 'finished'

Called macro defined in macro 'included'

 7 | macro finished

Which expanded to:

 > 1 |         columns_to_instance_vars
 > 2 |       
Error: expanding macro


There was a problem expanding macro 'columns_to_instance_vars'

Called macro defined in src/clear/model/json_deserialize.cr:19:1

 19 | macro columns_to_instance_vars

Which expanded to:

 >   1 |   # :nodoc:
 >   2 |   struct Assigner
 >   3 |     include JSON::Serializable
 >   4 | 
 >   5 |     
 >   6 |       @[JSON::Field(presence: true)]
 >   7 |       getter id : Int32  | Nil 
 >   8 |       @[JSON::Field(ignore: true)]
 >   9 |       getter? id_present : Bool
 >  10 |     
 >  11 |       @[JSON::Field(presence: true)]
 >  12 |       getter title : String  | Nil 
 >  13 |       @[JSON::Field(ignore: true)]
 >  14 |       getter? title_present : Bool
 >  15 |     
 >  16 |       @[JSON::Field(presence: true)]
 >  17 |       getter tags : Array(String)  | Nil 
 >  18 |       @[JSON::Field(ignore: true)]
 >  19 |       getter? tags_present : Bool
 >  20 |     
 >  21 |       @[JSON::Field(presence: true)]
 >  22 |       getter flags_other_column_name : Array(Int64)  | Nil 
 >  23 |       @[JSON::Field(ignore: true)]
 >  24 |       getter? flags_other_column_name_present : Bool
 >  25 |     
 >  26 |       @[JSON::Field(presence: true)]
 >  27 |       getter content : String  | Nil 
 >  28 |       @[JSON::Field(ignore: true)]
 >  29 |       getter? content_present : Bool
 >  30 |     
 >  31 |       @[JSON::Field(presence: true)]
 >  32 |       getter published : Bool  | Nil 
 >  33 |       @[JSON::Field(ignore: true)]
 >  34 |       getter? published_present : Bool
 >  35 |     
 >  36 |       @[JSON::Field(presence: true)]
 >  37 |       getter user_id : Int32  | Nil 
 >  38 |       @[JSON::Field(ignore: true)]
 >  39 |       getter? user_id_present : Bool
 >  40 |     
 >  41 |       @[JSON::Field(presence: true)]
 >  42 |       getter category_id : Int32 | ::Nil 
 >  43 |       @[JSON::Field(ignore: true)]
 >  44 |       getter? category_id_present : Bool
 >  45 |     
 >  46 | 
 >  47 |     # Create a new empty model and fill the columns with object's instance variables
 >  48 |     # Trusted flag set to true will allow mass assignment without protection
 >  49 |     def create(trusted : Bool)
 >  50 |       assign_columns(Post.new, trusted)
 >  51 |     end
 >  52 | 
 >  53 |     # Update the inputted model and assign the columns with object's instance variables
 >  54 |     # Trusted flag set to true will allow mass assignment without protection
 >  55 |     def update(model, trusted : Bool)
 >  56 |       assign_columns(model, trusted)
 >  57 |     end
 >  58 | 
 >  59 |     macro finished
 >  60 |       # Assign properties to the model inputted with object's instance variables
 >  61 |       # Trusted flag set to true will allow mass assignment without protection
 >  62 |       protected def assign_columns(model, trusted : Bool)
 >  63 |         
 >  64 |           if (true || trusted) && self.id_present?
 >  65 |             __temp_121 = self.id
 >  66 |             
 >  67 |               model.id = __temp_121 unless __temp_121.nil?
 >  68 |             
 >  69 |           end
 >  70 |         
 >  71 |           if (true || trusted) && self.title_present?
 >  72 |             __temp_121 = self.title
 >  73 |             
 >  74 |               model.title = __temp_121 unless __temp_121.nil?
 >  75 |             
 >  76 |           end
 >  77 |         
 >  78 |           if (true || trusted) && self.tags_present?
 >  79 |             __temp_121 = self.tags
 >  80 |             
 >  81 |               model.tags = __temp_121 unless __temp_121.nil?
 >  82 |             
 >  83 |           end
 >  84 |         
 >  85 |           if (true || trusted) && self.flags_other_column_name_present?
 >  86 |             __temp_121 = self.flags_other_column_name
 >  87 |             
 >  88 |               model.flags_other_column_name = __temp_121 unless __temp_121.nil?
 >  89 |             
 >  90 |           end
 >  91 |         
 >  92 |           if (true || trusted) && self.content_present?
 >  93 |             __temp_121 = self.content
 >  94 |             
 >  95 |               model.content = __temp_121 unless __temp_121.nil?
 >  96 |             
 >  97 |           end
 >  98 |         
 >  99 |           if (true || trusted) && self.published_present?
 > 100 |             __temp_121 = self.published
 > 101 |             
 > 102 |               model.published = __temp_121 unless __temp_121.nil?
 > 103 |             
 > 104 |           end
 > 105 |         
 > 106 |           if (true || trusted) && self.user_id_present?
 > 107 |             __temp_121 = self.user_id
 > 108 |             
 > 109 |               model.user_id = __temp_121 unless __temp_121.nil?
 > 110 |             
 > 111 |           end
 > 112 |         
 > 113 |           if (true || trusted) && self.category_id_present?
 > 114 |             __temp_121 = self.category_id
 > 115 |             
 > 116 |               model.category_id = __temp_121
 > 117 |             
 > 118 |           end
 > 119 |         
 > 120 | 
 > 121 |         model
 > 122 |       end
 > 123 |     end
 > 124 |   end
 > 125 | 
 > 126 |   # Create a new empty model and fill the columns from json. Returns the new model
 > 127 |   #
 > 128 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 129 |   def self.from_json(string_or_io : String | IO, trusted : Bool = false)
 > 130 |     Assigner.from_json(string_or_io).create(trusted)
 > 131 |   end
 > 132 | 
 > 133 |   # Create a new model from json and save it. Returns the model.
 > 134 |   #
 > 135 |   # The model may not be saved due to validation failure;
 > 136 |   # check the returned model `errors?` and `persisted?` flags.
 > 137 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 138 |   def self.create_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 139 |     mdl = self.from_json(string_or_io, trusted)
 > 140 |     mdl.save
 > 141 |     mdl
 > 142 |   end
 > 143 | 
 > 144 |   # Create a new model from json and save it. Returns the model.
 > 145 |   #
 > 146 |   # Returns the newly inserted model
 > 147 |   # Raises an exception if validation failed during the saving process.
 > 148 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 149 |   def self.create_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 150 |     self.from_json(string_or_io, trusted).save!
 > 151 |   end
 > 152 | 
 > 153 |   # Set the fields from json passed as argument
 > 154 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 155 |   def set_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 156 |     Assigner.from_json(string_or_io).update(self, trusted)
 > 157 |   end
 > 158 | 
 > 159 |   # Set the fields from json passed as argument and call `save` on the object
 > 160 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 161 |   def update_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 162 |     mdl = set_from_json(string_or_io, trusted)
 > 163 |     mdl.save
 > 164 |     mdl
 > 165 |   end
 > 166 | 
 > 167 |   # Set the fields from json passed as argument and call `save!` on the object
 > 168 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 169 |   def update_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 170 |     set_from_json(string_or_io, trusted).save!
 > 171 |   end
Error: instantiating 'Post::Assigner#create(Bool)'


There was a problem expanding macro 'finished'

Called macro defined in macro 'included'

 7 | macro finished

Which expanded to:

 > 1 |         columns_to_instance_vars
 > 2 |       
Error: expanding macro


There was a problem expanding macro 'columns_to_instance_vars'

Called macro defined in src/clear/model/json_deserialize.cr:19:1

 19 | macro columns_to_instance_vars

Which expanded to:

 >   1 |   # :nodoc:
 >   2 |   struct Assigner
 >   3 |     include JSON::Serializable
 >   4 | 
 >   5 |     
 >   6 |       @[JSON::Field(presence: true)]
 >   7 |       getter id : Int32  | Nil 
 >   8 |       @[JSON::Field(ignore: true)]
 >   9 |       getter? id_present : Bool
 >  10 |     
 >  11 |       @[JSON::Field(presence: true)]
 >  12 |       getter title : String  | Nil 
 >  13 |       @[JSON::Field(ignore: true)]
 >  14 |       getter? title_present : Bool
 >  15 |     
 >  16 |       @[JSON::Field(presence: true)]
 >  17 |       getter tags : Array(String)  | Nil 
 >  18 |       @[JSON::Field(ignore: true)]
 >  19 |       getter? tags_present : Bool
 >  20 |     
 >  21 |       @[JSON::Field(presence: true)]
 >  22 |       getter flags_other_column_name : Array(Int64)  | Nil 
 >  23 |       @[JSON::Field(ignore: true)]
 >  24 |       getter? flags_other_column_name_present : Bool
 >  25 |     
 >  26 |       @[JSON::Field(presence: true)]
 >  27 |       getter content : String  | Nil 
 >  28 |       @[JSON::Field(ignore: true)]
 >  29 |       getter? content_present : Bool
 >  30 |     
 >  31 |       @[JSON::Field(presence: true)]
 >  32 |       getter published : Bool  | Nil 
 >  33 |       @[JSON::Field(ignore: true)]
 >  34 |       getter? published_present : Bool
 >  35 |     
 >  36 |       @[JSON::Field(presence: true)]
 >  37 |       getter user_id : Int32  | Nil 
 >  38 |       @[JSON::Field(ignore: true)]
 >  39 |       getter? user_id_present : Bool
 >  40 |     
 >  41 |       @[JSON::Field(presence: true)]
 >  42 |       getter category_id : Int32 | ::Nil 
 >  43 |       @[JSON::Field(ignore: true)]
 >  44 |       getter? category_id_present : Bool
 >  45 |     
 >  46 | 
 >  47 |     # Create a new empty model and fill the columns with object's instance variables
 >  48 |     # Trusted flag set to true will allow mass assignment without protection
 >  49 |     def create(trusted : Bool)
 >  50 |       assign_columns(Post.new, trusted)
 >  51 |     end
 >  52 | 
 >  53 |     # Update the inputted model and assign the columns with object's instance variables
 >  54 |     # Trusted flag set to true will allow mass assignment without protection
 >  55 |     def update(model, trusted : Bool)
 >  56 |       assign_columns(model, trusted)
 >  57 |     end
 >  58 | 
 >  59 |     macro finished
 >  60 |       # Assign properties to the model inputted with object's instance variables
 >  61 |       # Trusted flag set to true will allow mass assignment without protection
 >  62 |       protected def assign_columns(model, trusted : Bool)
 >  63 |         
 >  64 |           if (true || trusted) && self.id_present?
 >  65 |             __temp_121 = self.id
 >  66 |             
 >  67 |               model.id = __temp_121 unless __temp_121.nil?
 >  68 |             
 >  69 |           end
 >  70 |         
 >  71 |           if (true || trusted) && self.title_present?
 >  72 |             __temp_121 = self.title
 >  73 |             
 >  74 |               model.title = __temp_121 unless __temp_121.nil?
 >  75 |             
 >  76 |           end
 >  77 |         
 >  78 |           if (true || trusted) && self.tags_present?
 >  79 |             __temp_121 = self.tags
 >  80 |             
 >  81 |               model.tags = __temp_121 unless __temp_121.nil?
 >  82 |             
 >  83 |           end
 >  84 |         
 >  85 |           if (true || trusted) && self.flags_other_column_name_present?
 >  86 |             __temp_121 = self.flags_other_column_name
 >  87 |             
 >  88 |               model.flags_other_column_name = __temp_121 unless __temp_121.nil?
 >  89 |             
 >  90 |           end
 >  91 |         
 >  92 |           if (true || trusted) && self.content_present?
 >  93 |             __temp_121 = self.content
 >  94 |             
 >  95 |               model.content = __temp_121 unless __temp_121.nil?
 >  96 |             
 >  97 |           end
 >  98 |         
 >  99 |           if (true || trusted) && self.published_present?
 > 100 |             __temp_121 = self.published
 > 101 |             
 > 102 |               model.published = __temp_121 unless __temp_121.nil?
 > 103 |             
 > 104 |           end
 > 105 |         
 > 106 |           if (true || trusted) && self.user_id_present?
 > 107 |             __temp_121 = self.user_id
 > 108 |             
 > 109 |               model.user_id = __temp_121 unless __temp_121.nil?
 > 110 |             
 > 111 |           end
 > 112 |         
 > 113 |           if (true || trusted) && self.category_id_present?
 > 114 |             __temp_121 = self.category_id
 > 115 |             
 > 116 |               model.category_id = __temp_121
 > 117 |             
 > 118 |           end
 > 119 |         
 > 120 | 
 > 121 |         model
 > 122 |       end
 > 123 |     end
 > 124 |   end
 > 125 | 
 > 126 |   # Create a new empty model and fill the columns from json. Returns the new model
 > 127 |   #
 > 128 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 129 |   def self.from_json(string_or_io : String | IO, trusted : Bool = false)
 > 130 |     Assigner.from_json(string_or_io).create(trusted)
 > 131 |   end
 > 132 | 
 > 133 |   # Create a new model from json and save it. Returns the model.
 > 134 |   #
 > 135 |   # The model may not be saved due to validation failure;
 > 136 |   # check the returned model `errors?` and `persisted?` flags.
 > 137 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 138 |   def self.create_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 139 |     mdl = self.from_json(string_or_io, trusted)
 > 140 |     mdl.save
 > 141 |     mdl
 > 142 |   end
 > 143 | 
 > 144 |   # Create a new model from json and save it. Returns the model.
 > 145 |   #
 > 146 |   # Returns the newly inserted model
 > 147 |   # Raises an exception if validation failed during the saving process.
 > 148 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 149 |   def self.create_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 150 |     self.from_json(string_or_io, trusted).save!
 > 151 |   end
 > 152 | 
 > 153 |   # Set the fields from json passed as argument
 > 154 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 155 |   def set_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 156 |     Assigner.from_json(string_or_io).update(self, trusted)
 > 157 |   end
 > 158 | 
 > 159 |   # Set the fields from json passed as argument and call `save` on the object
 > 160 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 161 |   def update_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 162 |     mdl = set_from_json(string_or_io, trusted)
 > 163 |     mdl.save
 > 164 |     mdl
 > 165 |   end
 > 166 | 
 > 167 |   # Set the fields from json passed as argument and call `save!` on the object
 > 168 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 169 |   def update_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 170 |     set_from_json(string_or_io, trusted).save!
 > 171 |   end
Error: instantiating 'assign_columns(Post, Bool)'


There was a problem expanding macro 'columns_to_instance_vars'

Called macro defined in src/clear/model/json_deserialize.cr:19:1

 19 | macro columns_to_instance_vars

Which expanded to:

 >   1 |   # :nodoc:
 >   2 |   struct Assigner
 >   3 |     include JSON::Serializable
 >   4 | 
 >   5 |     
 >   6 |       @[JSON::Field(presence: true)]
 >   7 |       getter id : Int32  | Nil 
 >   8 |       @[JSON::Field(ignore: true)]
 >   9 |       getter? id_present : Bool
 >  10 |     
 >  11 |       @[JSON::Field(presence: true)]
 >  12 |       getter title : String  | Nil 
 >  13 |       @[JSON::Field(ignore: true)]
 >  14 |       getter? title_present : Bool
 >  15 |     
 >  16 |       @[JSON::Field(presence: true)]
 >  17 |       getter tags : Array(String)  | Nil 
 >  18 |       @[JSON::Field(ignore: true)]
 >  19 |       getter? tags_present : Bool
 >  20 |     
 >  21 |       @[JSON::Field(presence: true)]
 >  22 |       getter flags_other_column_name : Array(Int64)  | Nil 
 >  23 |       @[JSON::Field(ignore: true)]
 >  24 |       getter? flags_other_column_name_present : Bool
 >  25 |     
 >  26 |       @[JSON::Field(presence: true)]
 >  27 |       getter content : String  | Nil 
 >  28 |       @[JSON::Field(ignore: true)]
 >  29 |       getter? content_present : Bool
 >  30 |     
 >  31 |       @[JSON::Field(presence: true)]
 >  32 |       getter published : Bool  | Nil 
 >  33 |       @[JSON::Field(ignore: true)]
 >  34 |       getter? published_present : Bool
 >  35 |     
 >  36 |       @[JSON::Field(presence: true)]
 >  37 |       getter user_id : Int32  | Nil 
 >  38 |       @[JSON::Field(ignore: true)]
 >  39 |       getter? user_id_present : Bool
 >  40 |     
 >  41 |       @[JSON::Field(presence: true)]
 >  42 |       getter category_id : Int32 | ::Nil 
 >  43 |       @[JSON::Field(ignore: true)]
 >  44 |       getter? category_id_present : Bool
 >  45 |     
 >  46 | 
 >  47 |     # Create a new empty model and fill the columns with object's instance variables
 >  48 |     # Trusted flag set to true will allow mass assignment without protection
 >  49 |     def create(trusted : Bool)
 >  50 |       assign_columns(Post.new, trusted)
 >  51 |     end
 >  52 | 
 >  53 |     # Update the inputted model and assign the columns with object's instance variables
 >  54 |     # Trusted flag set to true will allow mass assignment without protection
 >  55 |     def update(model, trusted : Bool)
 >  56 |       assign_columns(model, trusted)
 >  57 |     end
 >  58 | 
 >  59 |     macro finished
 >  60 |       # Assign properties to the model inputted with object's instance variables
 >  61 |       # Trusted flag set to true will allow mass assignment without protection
 >  62 |       protected def assign_columns(model, trusted : Bool)
 >  63 |         
 >  64 |           if (true || trusted) && self.id_present?
 >  65 |             __temp_121 = self.id
 >  66 |             
 >  67 |               model.id = __temp_121 unless __temp_121.nil?
 >  68 |             
 >  69 |           end
 >  70 |         
 >  71 |           if (true || trusted) && self.title_present?
 >  72 |             __temp_121 = self.title
 >  73 |             
 >  74 |               model.title = __temp_121 unless __temp_121.nil?
 >  75 |             
 >  76 |           end
 >  77 |         
 >  78 |           if (true || trusted) && self.tags_present?
 >  79 |             __temp_121 = self.tags
 >  80 |             
 >  81 |               model.tags = __temp_121 unless __temp_121.nil?
 >  82 |             
 >  83 |           end
 >  84 |         
 >  85 |           if (true || trusted) && self.flags_other_column_name_present?
 >  86 |             __temp_121 = self.flags_other_column_name
 >  87 |             
 >  88 |               model.flags_other_column_name = __temp_121 unless __temp_121.nil?
 >  89 |             
 >  90 |           end
 >  91 |         
 >  92 |           if (true || trusted) && self.content_present?
 >  93 |             __temp_121 = self.content
 >  94 |             
 >  95 |               model.content = __temp_121 unless __temp_121.nil?
 >  96 |             
 >  97 |           end
 >  98 |         
 >  99 |           if (true || trusted) && self.published_present?
 > 100 |             __temp_121 = self.published
 > 101 |             
 > 102 |               model.published = __temp_121 unless __temp_121.nil?
 > 103 |             
 > 104 |           end
 > 105 |         
 > 106 |           if (true || trusted) && self.user_id_present?
 > 107 |             __temp_121 = self.user_id
 > 108 |             
 > 109 |               model.user_id = __temp_121 unless __temp_121.nil?
 > 110 |             
 > 111 |           end
 > 112 |         
 > 113 |           if (true || trusted) && self.category_id_present?
 > 114 |             __temp_121 = self.category_id
 > 115 |             
 > 116 |               model.category_id = __temp_121
 > 117 |             
 > 118 |           end
 > 119 |         
 > 120 | 
 > 121 |         model
 > 122 |       end
 > 123 |     end
 > 124 |   end
 > 125 | 
 > 126 |   # Create a new empty model and fill the columns from json. Returns the new model
 > 127 |   #
 > 128 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 129 |   def self.from_json(string_or_io : String | IO, trusted : Bool = false)
 > 130 |     Assigner.from_json(string_or_io).create(trusted)
 > 131 |   end
 > 132 | 
 > 133 |   # Create a new model from json and save it. Returns the model.
 > 134 |   #
 > 135 |   # The model may not be saved due to validation failure;
 > 136 |   # check the returned model `errors?` and `persisted?` flags.
 > 137 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 138 |   def self.create_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 139 |     mdl = self.from_json(string_or_io, trusted)
 > 140 |     mdl.save
 > 141 |     mdl
 > 142 |   end
 > 143 | 
 > 144 |   # Create a new model from json and save it. Returns the model.
 > 145 |   #
 > 146 |   # Returns the newly inserted model
 > 147 |   # Raises an exception if validation failed during the saving process.
 > 148 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 149 |   def self.create_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 150 |     self.from_json(string_or_io, trusted).save!
 > 151 |   end
 > 152 | 
 > 153 |   # Set the fields from json passed as argument
 > 154 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 155 |   def set_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 156 |     Assigner.from_json(string_or_io).update(self, trusted)
 > 157 |   end
 > 158 | 
 > 159 |   # Set the fields from json passed as argument and call `save` on the object
 > 160 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 161 |   def update_from_json(string_or_io : String | IO, trusted : Bool = false)
 > 162 |     mdl = set_from_json(string_or_io, trusted)
 > 163 |     mdl.save
 > 164 |     mdl
 > 165 |   end
 > 166 | 
 > 167 |   # Set the fields from json passed as argument and call `save!` on the object
 > 168 |   # Trusted flag set to true will allow mass assignment without protection, FALSE by default
 > 169 |   def update_from_json!(string_or_io : String | IO, trusted : Bool = false)
 > 170 |     set_from_json(string_or_io, trusted).save!
 > 171 |   end
Error: expanding macro


There was a problem expanding macro 'finished'

Called macro defined in macro 'columns_to_instance_vars'

 59 | macro finished

Which expanded to:

 >  1 |       # Assign properties to the model inputted with object's instance variables
 >  2 |       # Trusted flag set to true will allow mass assignment without protection
 >  3 |       protected def assign_columns(model, trusted : Bool)
 >  4 |         
 >  5 |           if (true || trusted) && self.id_present?
 >  6 |             __temp_121 = self.id
 >  7 |             
 >  8 |               model.id = __temp_121 unless __temp_121.nil?
 >  9 |             
 > 10 |           end
 > 11 |         
 > 12 |           if (true || trusted) && self.title_present?
 > 13 |             __temp_121 = self.title
 > 14 |             
 > 15 |               model.title = __temp_121 unless __temp_121.nil?
 > 16 |             
 > 17 |           end
 > 18 |         
 > 19 |           if (true || trusted) && self.tags_present?
 > 20 |             __temp_121 = self.tags
 > 21 |             
 > 22 |               model.tags = __temp_121 unless __temp_121.nil?
 > 23 |             
 > 24 |           end
 > 25 |         
 > 26 |           if (true || trusted) && self.flags_other_column_name_present?
 > 27 |             __temp_121 = self.flags_other_column_name
 > 28 |             
 > 29 |               model.flags_other_column_name = __temp_121 unless __temp_121.nil?
 > 30 |             
 > 31 |           end
 > 32 |         
 > 33 |           if (true || trusted) && self.content_present?
 > 34 |             __temp_121 = self.content
 > 35 |             
 > 36 |               model.content = __temp_121 unless __temp_121.nil?
 > 37 |             
 > 38 |           end
 > 39 |         
 > 40 |           if (true || trusted) && self.published_present?
 > 41 |             __temp_121 = self.published
 > 42 |             
 > 43 |               model.published = __temp_121 unless __temp_121.nil?
 > 44 |             
 > 45 |           end
 > 46 |         
 > 47 |           if (true || trusted) && self.user_id_present?
 > 48 |             __temp_121 = self.user_id
 > 49 |             
 > 50 |               model.user_id = __temp_121 unless __temp_121.nil?
 > 51 |             
 > 52 |           end
 > 53 |         
 > 54 |           if (true || trusted) && self.category_id_present?
 > 55 |             __temp_121 = self.category_id
 > 56 |             
 > 57 |               model.category_id = __temp_121
 > 58 |             
 > 59 |           end
 > 60 |         
 > 61 | 
 > 62 |         model
 > 63 |       end
 > 64 |     
Error: undefined method 'flags_other_column_name=' for Post

Post trace:

  macro finished (in expanded macro: columns_to_instance_vars:59):29

                  model.flags_other_column_name = __temp_121 unless __temp_121.nil?


  macro finished (in expanded macro: columns_to_instance_vars:59):3

          protected def assign_columns(model, trusted : Bool)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions