flex_columns 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/CHANGES.md +4 -0
 - data/README.md +2 -2
 - data/lib/flex_columns/active_record/base.rb +1 -2
 - data/lib/flex_columns/definition/fake_column.rb +29 -0
 - data/lib/flex_columns/definition/flex_column_contents_class.rb +46 -16
 - data/lib/flex_columns/has_flex_columns.rb +16 -2
 - data/lib/flex_columns/version.rb +1 -1
 - data/spec/flex_columns/helpers/system_helpers.rb +8 -0
 - data/spec/flex_columns/system/basic_system_spec.rb +1 -2
 - data/spec/flex_columns/system/dynamism_system_spec.rb +76 -0
 - data/spec/flex_columns/system/performance_system_spec.rb +12 -12
 - data/spec/flex_columns/unit/definition/fake_column_spec.rb +8 -0
 - data/spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb +42 -0
 - data/spec/flex_columns/unit/has_flex_columns_spec.rb +37 -0
 - metadata +5 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- 
         
     | 
| 
       2 
     | 
    
         
            -
            SHA512: 
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz: a346cd4387b83db2754cd6d18db49a616015ca230a0b18134f0a7176b4f206778a7f778cec4b97e84c59dfb0358339a2106b1e8656be922a54b2d0143867b1da
         
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz: bebc4830bc2ea67bfa2152cca4587d751dd13da67c4afe22ea288e4522079510aaf2aa42b32fbff72a6b2af4c930ada099fafadb063cb384bb84f30c1a3c05c4
         
     | 
| 
       5 
2 
     | 
    
         
             
            SHA1: 
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d883b205cd22c7aa6a6bda071d3ca52c7084e14e
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 88057e546d40a01a83ba499f0c9c4d4c5b0863af
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 040c456a7527585100159b68e0b1685e590fb30a75f1388107773de1501a6699d8b7903f891ccbc0b0e0f5a7cb44b647d734cf5e65279185723129580cb6f4be
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 951bfb6887b746545fcc7d5b8036d9a1efa5bdc31369e1b68fddfcf1bc482b10464d5f11a2d43cb4135ac9e140471cb5490ddee61e8ff41730e4fa03c0f82bb2
         
     | 
    
        data/CHANGES.md
    CHANGED
    
    | 
         @@ -1,5 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # `flex_columns` Changelog
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 1.0.7, 2014-04-07
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            * Fixed an issue where, if you defined a model class when its table didn't exist, and then created its table while the Ruby process was still running, you still couldn't access any flex-column attributes — because we would simply skip defining them entirely if the table didn't exist. Now, we define them, assuming the columns exist and are of type `:string` (and `null`able) if the table doesn't exist, and replace them with the actual column definition once the table exists. (You need to call `.reset_column_information` on the model class to make this happen, just as you do with any changes to the underlying table of an ActiveRecord model.)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       3 
7 
     | 
    
         
             
            ## 1.0.6, 2014-04-07
         
     | 
| 
       4 
8 
     | 
    
         | 
| 
       5 
9 
     | 
    
         
             
            * Fixed an issue where Float::INFINITY and Float::NaN could not be stored in a flex column.
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -110,13 +110,13 @@ As a snapshot of all possibilities: 
     | 
|
| 
       110 
110 
     | 
    
         
             
            There's lots more, too:
         
     | 
| 
       111 
111 
     | 
    
         | 
| 
       112 
112 
     | 
    
         
             
            * Complete validations support: the flex-column object includes ActiveModel::Validations, so every single Rails validation (or custom validations) will work perfectly
         
     | 
| 
       113 
     | 
    
         
            -
            * Bulk operations, for avoiding ActiveRecord instantiation (efficiently operate using raw  
     | 
| 
      
 113 
     | 
    
         
            +
            * Bulk operations, for avoiding ActiveRecord instantiation (efficiently operate using raw `select_all` and `activerecord-import` or similar systems)
         
     | 
| 
       114 
114 
     | 
    
         
             
            * Transparently compresses JSON data in the column using GZip, if it's typed as binary (`BINARY`, `VARBINARY`, `CLOB`, etc.); you can fully control this, or turn it off if you want
         
     | 
| 
       115 
115 
     | 
    
         
             
            * Happily allows definition and redefinition of flex columns at any time, for full dynamism and compatibility with development mode of Rails
         
     | 
| 
       116 
116 
     | 
    
         
             
            * Rich error hierarchy and detailed exception messages — you will know exactly what went wrong when something goes wrong
         
     | 
| 
       117 
117 
     | 
    
         
             
            * Include flex columns across associations, with control over exactly what's delegated and visibility of those methods (public or private)
         
     | 
| 
       118 
118 
     | 
    
         
             
            * Control whether attribute methods generated are public (default) or private (to encourage encapsulation)
         
     | 
| 
       119 
     | 
    
         
            -
            * "Types": automatically adds validations that require fields to comply with database types like  
     | 
| 
      
 119 
     | 
    
         
            +
            * "Types": automatically adds validations that require fields to comply with database types like `:integer`, `:string`, `:timestamp`, etc.
         
     | 
| 
       120 
120 
     | 
    
         
             
            * Decide whether to preserve (the default) or delete keys from the underlying JSON that aren't defined in the flex column — lets you ensure database data is of the highest quality, or be compatible with any other storage mechanisms
         
     | 
| 
       121 
121 
     | 
    
         | 
| 
       122 
122 
     | 
    
         
             
            ### Documentation
         
     | 
| 
         @@ -60,8 +60,7 @@ module FlexColumns 
     | 
|
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                      reason = nil
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                      reason ||= :column if columns.detect { |c| c.name.to_s == base_name }
         
     | 
| 
       64 
     | 
    
         
            -
                      # return false if method_defined?(base_name) || method_defined?("#{base_name}=")
         
     | 
| 
      
 63 
     | 
    
         
            +
                      reason ||= :column if table_exists? && columns.detect { |c| c.name.to_s == base_name }
         
     | 
| 
       65 
64 
     | 
    
         
             
                      reason ||= :instance_method if instance_methods(false).map(&:to_s).include?(base_name.to_s)
         
     | 
| 
       66 
65 
     | 
    
         | 
| 
       67 
66 
     | 
    
         
             
                      (! reason)
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module FlexColumns
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Definition
         
     | 
| 
      
 3 
     | 
    
         
            +
                # This is a class that complies with just enough of the ActiveRecord interface to columns to be able to be
         
     | 
| 
      
 4 
     | 
    
         
            +
                # swapped in for it, in our code.
         
     | 
| 
      
 5 
     | 
    
         
            +
                #
         
     | 
| 
      
 6 
     | 
    
         
            +
                # We use this in just one case: when you declare a flex column on a model class whose underlying table doesn't
         
     | 
| 
      
 7 
     | 
    
         
            +
                # exist. If you call +.reset_column_information+ on the model in question, we'll pick up the new, actual column
         
     | 
| 
      
 8 
     | 
    
         
            +
                # (assuming the table exists now), but, until then, we'll use this.
         
     | 
| 
      
 9 
     | 
    
         
            +
                class FakeColumn
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_reader :name
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def null
         
     | 
| 
      
 17 
     | 
    
         
            +
                    true
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def type
         
     | 
| 
      
 21 
     | 
    
         
            +
                    :string
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def limit
         
     | 
| 
      
 25 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'flex_columns/definition/fake_column'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module FlexColumns
         
     | 
| 
       2 
4 
     | 
    
         
             
              module Definition
         
     | 
| 
       3 
5 
     | 
    
         
             
                # When you declare a flex column, we actually generate a brand-new Class for that column; instances of that flex
         
     | 
| 
         @@ -198,25 +200,11 @@ module FlexColumns 
     | 
|
| 
       198 
200 
     | 
    
         | 
| 
       199 
201 
     | 
    
         
             
                    raise ArgumentError, "Invalid column name: #{column_name.inspect}" unless column_name.kind_of?(Symbol)
         
     | 
| 
       200 
202 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
                     
     | 
| 
       202 
     | 
    
         
            -
                     
     | 
| 
       203 
     | 
    
         
            -
                      raise FlexColumns::Errors::NoSuchColumnError, %{You're trying to define a flex column #{column_name.inspect}, but
         
     | 
| 
       204 
     | 
    
         
            -
              the model you're defining it on, #{model_class.name}, seems to have no column
         
     | 
| 
       205 
     | 
    
         
            -
              named that.
         
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
              It has columns named: #{model_class.columns.map(&:name).sort_by(&:to_s).join(", ")}.}
         
     | 
| 
       208 
     | 
    
         
            -
                    end
         
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
                    unless column.type == :binary || column.text? || column.sql_type == "json" # for PostgreSQL >= 9.2, which has a native JSON data type
         
     | 
| 
       211 
     | 
    
         
            -
                      raise FlexColumns::Errors::InvalidColumnTypeError, %{You're trying to define a flex column #{column_name.inspect}, but
         
     | 
| 
       212 
     | 
    
         
            -
              that column (on model #{model_class.name}) isn't of a type that accepts text.
         
     | 
| 
       213 
     | 
    
         
            -
              That column is of type: #{column.type.inspect}.}
         
     | 
| 
       214 
     | 
    
         
            -
                    end
         
     | 
| 
      
 203 
     | 
    
         
            +
                    @model_class = model_class
         
     | 
| 
      
 204 
     | 
    
         
            +
                    @column = find_column(column_name)
         
     | 
| 
       215 
205 
     | 
    
         | 
| 
       216 
206 
     | 
    
         
             
                    validate_options(options)
         
     | 
| 
       217 
207 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
                    @model_class = model_class
         
     | 
| 
       219 
     | 
    
         
            -
                    @column = column
         
     | 
| 
       220 
208 
     | 
    
         
             
                    @options = options
         
     | 
| 
       221 
209 
     | 
    
         
             
                    @field_set = FlexColumns::Definition::FieldSet.new(self)
         
     | 
| 
       222 
210 
     | 
    
         | 
| 
         @@ -232,6 +220,14 @@ module FlexColumns 
     | 
|
| 
       232 
220 
     | 
    
         
             
                    block_result
         
     | 
| 
       233 
221 
     | 
    
         
             
                  end
         
     | 
| 
       234 
222 
     | 
    
         | 
| 
      
 223 
     | 
    
         
            +
                  # This method gets called when ActiveRecord::Base.reset_column_information is called on the underlying model;
         
     | 
| 
      
 224 
     | 
    
         
            +
                  # this simply updates our notion of what column is present. Most importantly, this will correctly switch us from
         
     | 
| 
      
 225 
     | 
    
         
            +
                  # a table-does-not-exist state to a table-exists state (if you migrate the table in), but it also will correctly
         
     | 
| 
      
 226 
     | 
    
         
            +
                  # switch from one column type to another, etc.
         
     | 
| 
      
 227 
     | 
    
         
            +
                  def reset_column_information
         
     | 
| 
      
 228 
     | 
    
         
            +
                    @column = find_column(column_name)
         
     | 
| 
      
 229 
     | 
    
         
            +
                  end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
       235 
231 
     | 
    
         
             
                  # Tells this class to re-publish all its methods to the DynamicMethodsModule it uses internally, and to the
         
     | 
| 
       236 
232 
     | 
    
         
             
                  # model class it's a part of.
         
     | 
| 
       237 
233 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -275,6 +271,40 @@ module FlexColumns 
     | 
|
| 
       275 
271 
     | 
    
         
             
                    end
         
     | 
| 
       276 
272 
     | 
    
         
             
                  end
         
     | 
| 
       277 
273 
     | 
    
         | 
| 
      
 274 
     | 
    
         
            +
                  # Given the name of a column, finds the column on the model and makes sure it complies with our
         
     | 
| 
      
 275 
     | 
    
         
            +
                  # requirements for columns we can store data in.
         
     | 
| 
      
 276 
     | 
    
         
            +
                  #
         
     | 
| 
      
 277 
     | 
    
         
            +
                  # However, if the underlying table doesn't currently exist, this creates a "fake" column object and returns it;
         
     | 
| 
      
 278 
     | 
    
         
            +
                  # this fake column object responds to just enough methods that we can use it successfully in this gem. This is
         
     | 
| 
      
 279 
     | 
    
         
            +
                  # used so that we can define flex columns on a model for a table that doesn't exist yet (typically, because it
         
     | 
| 
      
 280 
     | 
    
         
            +
                  # hasn't been migrated in yet), and effectively upgrade it using .reset_column_information, above, when it
         
     | 
| 
      
 281 
     | 
    
         
            +
                  # does exist.
         
     | 
| 
      
 282 
     | 
    
         
            +
                  def find_column(column_name)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    return create_temporary_fake_column(column_name) if (! @model_class.table_exists?)
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                    out = model_class.columns.detect { |c| c.name.to_s == column_name.to_s }
         
     | 
| 
      
 286 
     | 
    
         
            +
                    unless out
         
     | 
| 
      
 287 
     | 
    
         
            +
                      raise FlexColumns::Errors::NoSuchColumnError, %{You're trying to define a flex column #{column_name.inspect}, but
         
     | 
| 
      
 288 
     | 
    
         
            +
            the model you're defining it on, #{model_class.name}, seems to have no column
         
     | 
| 
      
 289 
     | 
    
         
            +
            named that.
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
            It has columns named: #{model_class.columns.map(&:name).sort_by(&:to_s).join(", ")}.}
         
     | 
| 
      
 292 
     | 
    
         
            +
                    end
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
                    unless out.type == :binary || out.text? || out.sql_type == "json" # for PostgreSQL >= 9.2, which has a native JSON data type
         
     | 
| 
      
 295 
     | 
    
         
            +
                      raise FlexColumns::Errors::InvalidColumnTypeError, %{You're trying to define a flex column #{column_name.inspect}, but
         
     | 
| 
      
 296 
     | 
    
         
            +
            that column (on model #{model_class.name}) isn't of a type that accepts text.
         
     | 
| 
      
 297 
     | 
    
         
            +
            That column is of type: #{out.type.inspect}.}
         
     | 
| 
      
 298 
     | 
    
         
            +
                    end
         
     | 
| 
      
 299 
     | 
    
         
            +
             
     | 
| 
      
 300 
     | 
    
         
            +
                    out
         
     | 
| 
      
 301 
     | 
    
         
            +
                  end
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                  # This creates a "fake" column that we can use if the underlying table doesn't exist yet.
         
     | 
| 
      
 304 
     | 
    
         
            +
                  def create_temporary_fake_column(column_name)
         
     | 
| 
      
 305 
     | 
    
         
            +
                    ::FlexColumns::Definition::FakeColumn.new(column_name)
         
     | 
| 
      
 306 
     | 
    
         
            +
                  end
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
       278 
308 
     | 
    
         
             
                  # Check all of our options to make sure they're correct. This is pretty defensive programming, but it is SO
         
     | 
| 
       279 
309 
     | 
    
         
             
                  # much nicer to get an error on startup if you've specified anything incorrectly than way on down the line,
         
     | 
| 
       280 
310 
     | 
    
         
             
                  # possibly in production, when it really matters.
         
     | 
| 
         @@ -17,6 +17,10 @@ module FlexColumns 
     | 
|
| 
       17 
17 
     | 
    
         
             
                included do
         
     | 
| 
       18 
18 
     | 
    
         
             
                  before_validation :_flex_columns_before_validation!
         
     | 
| 
       19 
19 
     | 
    
         
             
                  before_save :_flex_columns_before_save!
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 22 
     | 
    
         
            +
                    alias_method_chain :reset_column_information, :flex_columns
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
       20 
24 
     | 
    
         
             
                end
         
     | 
| 
       21 
25 
     | 
    
         | 
| 
       22 
26 
     | 
    
         
             
                # Before we save this model, make sure each flex column has a chance to serialize itself up and assign itself
         
     | 
| 
         @@ -133,6 +137,12 @@ module FlexColumns 
     | 
|
| 
       133 
137 
     | 
    
         
             
                end
         
     | 
| 
       134 
138 
     | 
    
         | 
| 
       135 
139 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
      
 140 
     | 
    
         
            +
                  def reset_column_information_with_flex_columns
         
     | 
| 
      
 141 
     | 
    
         
            +
                    reset_column_information_without_flex_columns
         
     | 
| 
      
 142 
     | 
    
         
            +
                    _flex_column_classes.each { |c| c.reset_column_information }
         
     | 
| 
      
 143 
     | 
    
         
            +
                    _flex_columns_redefine_all_methods!
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
       136 
146 
     | 
    
         
             
                  # Does this class have any flex columns? If this module has been included into a class, then the answer is true.
         
     | 
| 
       137 
147 
     | 
    
         
             
                  def has_any_flex_columns?
         
     | 
| 
       138 
148 
     | 
    
         
             
                    true
         
     | 
| 
         @@ -177,8 +187,6 @@ it has flex columns named: #{_all_flex_column_names.sort_by(&:to_s).inspect}.} 
     | 
|
| 
       177 
187 
     | 
    
         
             
                  # FlexColumns::Definition::FlexColumnContentsClass#setup!, and so can contain any of the options that that method
         
     | 
| 
       178 
188 
     | 
    
         
             
                  # accepts. The block, if passed, will be evaluated in the context of the generated class.
         
     | 
| 
       179 
189 
     | 
    
         
             
                  def flex_column(flex_column_name, options = { }, &block)
         
     | 
| 
       180 
     | 
    
         
            -
                    return unless table_exists?
         
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
190 
     | 
    
         
             
                    flex_column_name = _flex_column_normalize_name(flex_column_name)
         
     | 
| 
       183 
191 
     | 
    
         | 
| 
       184 
192 
     | 
    
         
             
                    new_class = Class.new(FlexColumns::Contents::FlexColumnContentsBase)
         
     | 
| 
         @@ -191,6 +199,12 @@ it has flex columns named: #{_all_flex_column_names.sort_by(&:to_s).inspect}.} 
     | 
|
| 
       191 
199 
     | 
    
         
             
                      _flex_column_object_for(flex_column_name)
         
     | 
| 
       192 
200 
     | 
    
         
             
                    end
         
     | 
| 
       193 
201 
     | 
    
         | 
| 
      
 202 
     | 
    
         
            +
                    _flex_columns_redefine_all_methods!
         
     | 
| 
      
 203 
     | 
    
         
            +
                  end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                  # Defines, or redefines, all methods on the dynamic-methods module associated with this model. This gets called
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # whenever we define a new flex column, or if you call .reset_column_information on the associated model.
         
     | 
| 
      
 207 
     | 
    
         
            +
                  def _flex_columns_redefine_all_methods!
         
     | 
| 
       194 
208 
     | 
    
         
             
                    _flex_column_dynamic_methods_module.remove_all_methods!
         
     | 
| 
       195 
209 
     | 
    
         
             
                    _flex_column_classes.each(&:sync_methods!)
         
     | 
| 
       196 
210 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/flex_columns/version.rb
    CHANGED
    
    
| 
         @@ -14,6 +14,14 @@ module FlexColumns 
     | 
|
| 
       14 
14 
     | 
    
         
             
                    end
         
     | 
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
      
 17 
     | 
    
         
            +
                  def reset_schema_cache!(model)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    if model.connection.respond_to?(:schema_cache)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      model.connection.schema_cache.clear!
         
     | 
| 
      
 20 
     | 
    
         
            +
                    elsif model.connection.respond_to?(:clear_cache!)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      model.connection.clear_cache!
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       17 
25 
     | 
    
         
             
                  def define_model_class(name, table_name, &block)
         
     | 
| 
       18 
26 
     | 
    
         
             
                    model_class = Class.new(::ActiveRecord::Base)
         
     | 
| 
       19 
27 
     | 
    
         
             
                    ::Object.send(:remove_const, name) if ::Object.const_defined?(name)
         
     | 
| 
         @@ -280,8 +280,6 @@ describe "FlexColumns basic operations" do 
     | 
|
| 
       280 
280 
     | 
    
         
             
                    user.name = 'User 1'
         
     | 
| 
       281 
281 
     | 
    
         
             
                    user.wants_email = [ 1, 2, 3 ]
         
     | 
| 
       282 
282 
     | 
    
         | 
| 
       283 
     | 
    
         
            -
                    $stderr.puts "ATTRIBUTES: #{user.attributes.keys.sort.inspect}"
         
     | 
| 
       284 
     | 
    
         
            -
             
     | 
| 
       285 
283 
     | 
    
         
             
                    user_json = JSON.dump(user)
         
     | 
| 
       286 
284 
     | 
    
         
             
                    parsed = JSON.parse(user_json)
         
     | 
| 
       287 
285 
     | 
    
         | 
| 
         @@ -308,6 +306,7 @@ describe "FlexColumns basic operations" do 
     | 
|
| 
       308 
306 
     | 
    
         
             
                      field :bbb
         
     | 
| 
       309 
307 
     | 
    
         
             
                    end
         
     | 
| 
       310 
308 
     | 
    
         
             
                  end
         
     | 
| 
      
 309 
     | 
    
         
            +
                  define_model_class(:UserBackdoor, 'flexcols_spec_users') { }
         
     | 
| 
       311 
310 
     | 
    
         | 
| 
       312 
311 
     | 
    
         
             
                  ::User.reset_column_information
         
     | 
| 
       313 
312 
     | 
    
         | 
| 
         @@ -26,6 +26,82 @@ describe "FlexColumns basic operations" do 
     | 
|
| 
       26 
26 
     | 
    
         
             
                end
         
     | 
| 
       27 
27 
     | 
    
         
             
              end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
              it "should handle the case where a table comes into existence after being defined -- like it will when running a bunch of migrations at once" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                migrate do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  drop_table :flexcols_coming_into_existence rescue nil
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                class ::Foo < ::ActiveRecord::Base
         
     | 
| 
      
 35 
     | 
    
         
            +
                  self.table_name = 'flexcols_coming_into_existence'
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  flex_column :foo do
         
     | 
| 
      
 38 
     | 
    
         
            +
                    field :att1
         
     | 
| 
      
 39 
     | 
    
         
            +
                    field :att2
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                migrate do
         
     | 
| 
      
 44 
     | 
    
         
            +
                  create_table :flexcols_coming_into_existence do |t|
         
     | 
| 
      
 45 
     | 
    
         
            +
                    t.string :name
         
     | 
| 
      
 46 
     | 
    
         
            +
                    t.string :foo
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                reset_schema_cache!(Foo)
         
     | 
| 
      
 51 
     | 
    
         
            +
                Foo.reset_column_information
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                f2 = Foo.new
         
     | 
| 
      
 54 
     | 
    
         
            +
                f2.att1 = "the_att1"
         
     | 
| 
      
 55 
     | 
    
         
            +
                f2.att2 = "the_att2"
         
     | 
| 
      
 56 
     | 
    
         
            +
                f2.save!
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                f2_again = Foo.find(f2.id)
         
     | 
| 
      
 59 
     | 
    
         
            +
                f2_again.att1.should == "the_att1"
         
     | 
| 
      
 60 
     | 
    
         
            +
                f2_again.att2.should == "the_att2"
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              it "should handle the case where a table comes into existence after being defined, and properly respect things like :binary and compression" do
         
     | 
| 
      
 64 
     | 
    
         
            +
                migrate do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  drop_table :flexcols_coming_into_existence rescue nil
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                class ::Foo < ::ActiveRecord::Base
         
     | 
| 
      
 69 
     | 
    
         
            +
                  self.table_name = 'flexcols_coming_into_existence'
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  flex_column :foo do
         
     | 
| 
      
 72 
     | 
    
         
            +
                    field :att1
         
     | 
| 
      
 73 
     | 
    
         
            +
                    field :att2
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                migrate do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  create_table :flexcols_coming_into_existence do |t|
         
     | 
| 
      
 79 
     | 
    
         
            +
                    t.string :name
         
     | 
| 
      
 80 
     | 
    
         
            +
                    t.binary :foo
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                reset_schema_cache!(Foo)
         
     | 
| 
      
 85 
     | 
    
         
            +
                Foo.reset_column_information
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                f2 = Foo.new
         
     | 
| 
      
 88 
     | 
    
         
            +
                f2.att1 = "the_att1"
         
     | 
| 
      
 89 
     | 
    
         
            +
                f2.att2 = "the_att2" * 1000
         
     | 
| 
      
 90 
     | 
    
         
            +
                f2.save!
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                f2_again = Foo.find(f2.id)
         
     | 
| 
      
 93 
     | 
    
         
            +
                f2_again.att1.should == "the_att1"
         
     | 
| 
      
 94 
     | 
    
         
            +
                f2_again.att2.should == "the_att2" * 1000
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                class ::FooBackdoor < ActiveRecord::Base
         
     | 
| 
      
 97 
     | 
    
         
            +
                  self.table_name = 'flexcols_coming_into_existence'
         
     | 
| 
      
 98 
     | 
    
         
            +
                end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                f2_backdoor = ::FooBackdoor.find(f2.id)
         
     | 
| 
      
 101 
     | 
    
         
            +
                data = f2_backdoor.foo
         
     | 
| 
      
 102 
     | 
    
         
            +
                data.should match(/^FC:01,1,/i)
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       29 
105 
     | 
    
         
             
              it "should let you redefine flex columns, and obey the new settings" do
         
     | 
| 
       30 
106 
     | 
    
         
             
                class ::User < ::ActiveRecord::Base
         
     | 
| 
       31 
107 
     | 
    
         
             
                  self.table_name = 'flexcols_spec_users'
         
     | 
| 
         @@ -130,8 +130,8 @@ describe "FlexColumns performance" do 
     | 
|
| 
       130 
130 
     | 
    
         | 
| 
       131 
131 
     | 
    
         
             
                before :each do
         
     | 
| 
       132 
132 
     | 
    
         
             
                  migrate do
         
     | 
| 
       133 
     | 
    
         
            -
                    drop_table : 
     | 
| 
       134 
     | 
    
         
            -
                    create_table : 
     | 
| 
      
 133 
     | 
    
         
            +
                    drop_table :flexcols_spec_users_2 rescue nil
         
     | 
| 
      
 134 
     | 
    
         
            +
                    create_table :flexcols_spec_users_2 do |t|
         
     | 
| 
       135 
135 
     | 
    
         
             
                      t.string :name, :null => false
         
     | 
| 
       136 
136 
     | 
    
         
             
                      t.text :text_attrs_nonnull, :null => false
         
     | 
| 
       137 
137 
     | 
    
         
             
                      t.text :text_attrs_null
         
     | 
| 
         @@ -140,9 +140,9 @@ describe "FlexColumns performance" do 
     | 
|
| 
       140 
140 
     | 
    
         
             
                    end
         
     | 
| 
       141 
141 
     | 
    
         
             
                  end
         
     | 
| 
       142 
142 
     | 
    
         | 
| 
       143 
     | 
    
         
            -
                  ::User 
     | 
| 
      
 143 
     | 
    
         
            +
                  # reset_schema_cache!(::User) if defined?(::User)
         
     | 
| 
       144 
144 
     | 
    
         | 
| 
       145 
     | 
    
         
            -
                  define_model_class(: 
     | 
| 
      
 145 
     | 
    
         
            +
                  define_model_class(:User2, 'flexcols_spec_users_2') do
         
     | 
| 
       146 
146 
     | 
    
         
             
                    flex_column :text_attrs_nonnull do
         
     | 
| 
       147 
147 
     | 
    
         
             
                      field :aaa
         
     | 
| 
       148 
148 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -157,9 +157,9 @@ describe "FlexColumns performance" do 
     | 
|
| 
       157 
157 
     | 
    
         
             
                    end
         
     | 
| 
       158 
158 
     | 
    
         
             
                  end
         
     | 
| 
       159 
159 
     | 
    
         | 
| 
       160 
     | 
    
         
            -
                  define_model_class(: 
     | 
| 
      
 160 
     | 
    
         
            +
                  define_model_class(:User2Backdoor, 'flexcols_spec_users_2') { }
         
     | 
| 
       161 
161 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
                  :: 
     | 
| 
      
 162 
     | 
    
         
            +
                  ::User2Backdoor.reset_column_information
         
     | 
| 
       163 
163 
     | 
    
         
             
                end
         
     | 
| 
       164 
164 
     | 
    
         | 
| 
       165 
165 
     | 
    
         
             
                it "should be smart enough to store an empty JSON string to the database, if necessary, if the column is non-NULL" do
         
     | 
| 
         @@ -171,11 +171,11 @@ describe "FlexColumns performance" do 
     | 
|
| 
       171 
171 
     | 
    
         
             
                  # those circumstances, rather than trying to work around this (pretty broken) behavior that's also a pretty rare
         
     | 
| 
       172 
172 
     | 
    
         
             
                  # edge case for us.
         
     | 
| 
       173 
173 
     | 
    
         
             
                  unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && @dh.database_type == :mysql
         
     | 
| 
       174 
     | 
    
         
            -
                    my_user = :: 
     | 
| 
      
 174 
     | 
    
         
            +
                    my_user = ::User2.new
         
     | 
| 
       175 
175 
     | 
    
         
             
                    my_user.name = 'User 1'
         
     | 
| 
       176 
176 
     | 
    
         
             
                    my_user.save!
         
     | 
| 
       177 
177 
     | 
    
         | 
| 
       178 
     | 
    
         
            -
                    user_bd = :: 
     | 
| 
      
 178 
     | 
    
         
            +
                    user_bd = ::User2Backdoor.find(my_user.id)
         
     | 
| 
       179 
179 
     | 
    
         
             
                    user_bd.name.should == 'User 1'
         
     | 
| 
       180 
180 
     | 
    
         
             
                    user_bd.text_attrs_nonnull.should == ""
         
     | 
| 
       181 
181 
     | 
    
         
             
                    user_bd.text_attrs_null.should == nil
         
     | 
| 
         @@ -185,7 +185,7 @@ describe "FlexColumns performance" do 
     | 
|
| 
       185 
185 
     | 
    
         
             
                end
         
     | 
| 
       186 
186 
     | 
    
         | 
| 
       187 
187 
     | 
    
         
             
                it "should store NULL or the empty string in the database, as appropriate, if there's no data left any more" do
         
     | 
| 
       188 
     | 
    
         
            -
                  my_user = :: 
     | 
| 
      
 188 
     | 
    
         
            +
                  my_user = ::User2.new
         
     | 
| 
       189 
189 
     | 
    
         
             
                  my_user.name = 'User 1'
         
     | 
| 
       190 
190 
     | 
    
         
             
                  my_user.aaa = 'aaa1'
         
     | 
| 
       191 
191 
     | 
    
         
             
                  my_user.bbb = 'bbb1'
         
     | 
| 
         @@ -193,21 +193,21 @@ describe "FlexColumns performance" do 
     | 
|
| 
       193 
193 
     | 
    
         
             
                  my_user.ddd = 'ddd1'
         
     | 
| 
       194 
194 
     | 
    
         
             
                  my_user.save!
         
     | 
| 
       195 
195 
     | 
    
         | 
| 
       196 
     | 
    
         
            -
                  user_bd = :: 
     | 
| 
      
 196 
     | 
    
         
            +
                  user_bd = ::User2Backdoor.find(my_user.id)
         
     | 
| 
       197 
197 
     | 
    
         
             
                  user_bd.name.should == 'User 1'
         
     | 
| 
       198 
198 
     | 
    
         
             
                  check_text_column_data(user_bd.text_attrs_nonnull, 'aaa', 'aaa1')
         
     | 
| 
       199 
199 
     | 
    
         
             
                  check_text_column_data(user_bd.text_attrs_null, 'bbb', 'bbb1')
         
     | 
| 
       200 
200 
     | 
    
         
             
                  check_binary_column_data(user_bd.binary_attrs_nonnull, 'ccc', 'ccc1')
         
     | 
| 
       201 
201 
     | 
    
         
             
                  check_binary_column_data(user_bd.binary_attrs_null, 'ddd', 'ddd1')
         
     | 
| 
       202 
202 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
                  user_again = :: 
     | 
| 
      
 203 
     | 
    
         
            +
                  user_again = ::User2.find(my_user.id)
         
     | 
| 
       204 
204 
     | 
    
         
             
                  user_again.aaa = nil
         
     | 
| 
       205 
205 
     | 
    
         
             
                  user_again.bbb = nil
         
     | 
| 
       206 
206 
     | 
    
         
             
                  user_again.ccc = nil
         
     | 
| 
       207 
207 
     | 
    
         
             
                  user_again.ddd = nil
         
     | 
| 
       208 
208 
     | 
    
         
             
                  user_again.save!
         
     | 
| 
       209 
209 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
                  user_bd_again = :: 
     | 
| 
      
 210 
     | 
    
         
            +
                  user_bd_again = ::User2Backdoor.find(my_user.id)
         
     | 
| 
       211 
211 
     | 
    
         
             
                  user_bd_again.name.should == 'User 1'
         
     | 
| 
       212 
212 
     | 
    
         
             
                  user_bd_again.text_attrs_nonnull.should == ""
         
     | 
| 
       213 
213 
     | 
    
         
             
                  user_bd_again.text_attrs_null.should == nil
         
     | 
| 
         @@ -10,6 +10,7 @@ describe FlexColumns::Definition::FlexColumnContentsClass do 
     | 
|
| 
       10 
10 
     | 
    
         
             
                @klass.send(:extend, FlexColumns::Definition::FlexColumnContentsClass)
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                @model_class = double("model_class")
         
     | 
| 
      
 13 
     | 
    
         
            +
                allow(@model_class).to receive(:table_exists?).with().and_return(true)
         
     | 
| 
       13 
14 
     | 
    
         
             
                allow(@model_class).to receive(:kind_of?).with(Class).and_return(true)
         
     | 
| 
       14 
15 
     | 
    
         
             
                allow(@model_class).to receive(:has_any_flex_columns?).with().and_return(true)
         
     | 
| 
       15 
16 
     | 
    
         
             
                allow(@model_class).to receive(:name).with().and_return(:mcname)
         
     | 
| 
         @@ -121,6 +122,12 @@ describe FlexColumns::Definition::FlexColumnContentsClass do 
     | 
|
| 
       121 
122 
     | 
    
         
             
                  e.message.should match(/integer/i)
         
     | 
| 
       122 
123 
     | 
    
         
             
                end
         
     | 
| 
       123 
124 
     | 
    
         | 
| 
      
 125 
     | 
    
         
            +
                it "should work if the table doesn't exist" do
         
     | 
| 
      
 126 
     | 
    
         
            +
                  allow(@model_class).to receive(:table_exists?).with().and_return(false)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  allow(@model_class).to receive(:columns).and_raise(StandardError) # to make sure we don't touch this
         
     | 
| 
      
 128 
     | 
    
         
            +
                  @klass.setup!(@model_class, :foo) { }
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
       124 
131 
     | 
    
         
             
                it "should work on a text column" do
         
     | 
| 
       125 
132 
     | 
    
         
             
                  @klass.setup!(@model_class, :foo) { }
         
     | 
| 
       126 
133 
     | 
    
         
             
                end
         
     | 
| 
         @@ -204,6 +211,41 @@ describe FlexColumns::Definition::FlexColumnContentsClass do 
     | 
|
| 
       204 
211 
     | 
    
         
             
                end
         
     | 
| 
       205 
212 
     | 
    
         
             
              end
         
     | 
| 
       206 
213 
     | 
    
         | 
| 
      
 214 
     | 
    
         
            +
              describe "reset_column_information" do
         
     | 
| 
      
 215 
     | 
    
         
            +
                it "should still generate a fake column if the table still doesn't exist" do
         
     | 
| 
      
 216 
     | 
    
         
            +
                  allow(@model_class).to receive(:table_exists?).with().and_return(false)
         
     | 
| 
      
 217 
     | 
    
         
            +
                  @klass.setup!(@model_class, :bar) { }
         
     | 
| 
      
 218 
     | 
    
         
            +
                  c = @klass.column
         
     | 
| 
      
 219 
     | 
    
         
            +
                  c.name.should == :bar
         
     | 
| 
      
 220 
     | 
    
         
            +
                  c.type.should == :string
         
     | 
| 
      
 221 
     | 
    
         
            +
                  c.null.should == true
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                  @klass.reset_column_information
         
     | 
| 
      
 224 
     | 
    
         
            +
                  c = @klass.column
         
     | 
| 
      
 225 
     | 
    
         
            +
                  c.name.should == :bar
         
     | 
| 
      
 226 
     | 
    
         
            +
                  c.type.should == :string
         
     | 
| 
      
 227 
     | 
    
         
            +
                  c.null.should == true
         
     | 
| 
      
 228 
     | 
    
         
            +
                end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                it "should pull a real column if the table does exist" do
         
     | 
| 
      
 231 
     | 
    
         
            +
                  allow(@column_bar).to receive(:null).with().and_return(false)
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                  allow(@model_class).to receive(:table_exists?).with().and_return(false)
         
     | 
| 
      
 234 
     | 
    
         
            +
                  @klass.setup!(@model_class, :bar) { }
         
     | 
| 
      
 235 
     | 
    
         
            +
                  c = @klass.column
         
     | 
| 
      
 236 
     | 
    
         
            +
                  c.name.should == :bar
         
     | 
| 
      
 237 
     | 
    
         
            +
                  c.type.should == :string
         
     | 
| 
      
 238 
     | 
    
         
            +
                  c.null.should == true
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
                  allow(@model_class).to receive(:table_exists?).with().and_return(true)
         
     | 
| 
      
 241 
     | 
    
         
            +
                  @klass.reset_column_information
         
     | 
| 
      
 242 
     | 
    
         
            +
                  c = @klass.column
         
     | 
| 
      
 243 
     | 
    
         
            +
                  c.name.should == :bar
         
     | 
| 
      
 244 
     | 
    
         
            +
                  c.type.should == :binary
         
     | 
| 
      
 245 
     | 
    
         
            +
                  c.null.should == false
         
     | 
| 
      
 246 
     | 
    
         
            +
                end
         
     | 
| 
      
 247 
     | 
    
         
            +
              end
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
       207 
249 
     | 
    
         
             
              describe "_flex_columns_create_column_data" do
         
     | 
| 
       208 
250 
     | 
    
         
             
                def expect_options_transform(class_options, length_limit, resulting_options, column_name = :foo, storage_string = double("storage_string"))
         
     | 
| 
       209 
251 
     | 
    
         
             
                  @klass.setup!(@model_class, column_name, class_options)
         
     | 
| 
         @@ -30,6 +30,10 @@ describe FlexColumns::HasFlexColumns do 
     | 
|
| 
       30 
30 
     | 
    
         
             
                    def table_exists?
         
     | 
| 
       31 
31 
     | 
    
         
             
                      true
         
     | 
| 
       32 
32 
     | 
    
         
             
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    def reset_column_information
         
     | 
| 
      
 35 
     | 
    
         
            +
                      # nothing here
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
       33 
37 
     | 
    
         
             
                  end
         
     | 
| 
       34 
38 
     | 
    
         | 
| 
       35 
39 
     | 
    
         
             
                  def _flex_column_object_for(column_name, create_if_needed = true)
         
     | 
| 
         @@ -59,6 +63,39 @@ describe FlexColumns::HasFlexColumns do 
     | 
|
| 
       59 
63 
     | 
    
         
             
                @klass.has_any_flex_columns?.should be
         
     | 
| 
       60 
64 
     | 
    
         
             
              end
         
     | 
| 
       61 
65 
     | 
    
         | 
| 
      
 66 
     | 
    
         
            +
              describe "#_flex_columns_redefine_all_methods" do
         
     | 
| 
      
 67 
     | 
    
         
            +
                it "should remove all methods on the module, and then add them back" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                  dmm = double("dmm")
         
     | 
| 
      
 69 
     | 
    
         
            +
                  expect(FlexColumns::Util::DynamicMethodsModule).to receive(:new).once.with(@klass, :FlexColumnsDynamicMethods).and_return(dmm)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  fcc1 = double("fcc1", :column_name => :foo)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  expect(Class).to receive(:new).once.ordered.with(FlexColumns::Contents::FlexColumnContentsBase).and_return(fcc1)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  expect(fcc1).to receive(:setup!).once.ordered.with(@klass, :foo, { })
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
         
     | 
| 
      
 76 
     | 
    
         
            +
                  expect(fcc1).to receive(:sync_methods!).once.ordered.with()
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  @klass.flex_column(:foo)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  fcc2 = double("fcc2", :column_name => :bar)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  expect(Class).to receive(:new).once.ordered.with(FlexColumns::Contents::FlexColumnContentsBase).and_return(fcc2)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  expect(fcc2).to receive(:setup!).once.ordered.with(@klass, :bar, { })
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
         
     | 
| 
      
 85 
     | 
    
         
            +
                  expect(fcc1).to receive(:sync_methods!).once.ordered.with()
         
     | 
| 
      
 86 
     | 
    
         
            +
                  expect(fcc2).to receive(:sync_methods!).once.ordered.with()
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  @klass.flex_column(:bar)
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
         
     | 
| 
      
 92 
     | 
    
         
            +
                  expect(fcc1).to receive(:sync_methods!).once.ordered.with()
         
     | 
| 
      
 93 
     | 
    
         
            +
                  expect(fcc2).to receive(:sync_methods!).once.ordered.with()
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  @klass._flex_columns_redefine_all_methods!
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
              end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       62 
99 
     | 
    
         
             
              describe "#flex_column" do
         
     | 
| 
       63 
100 
     | 
    
         
             
                it "should do nothing if the table doesn't exist" do
         
     | 
| 
       64 
101 
     | 
    
         
             
                  allow(@klass).to receive(:table_exists?).with().and_return(false)
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: flex_columns
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.7
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Andrew Geweke
         
     | 
| 
         @@ -9,7 +9,7 @@ autorequire: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            date: 2014-04- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2014-04-08 00:00:00 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: json
         
     | 
| 
         @@ -106,6 +106,7 @@ files: 
     | 
|
| 
       106 
106 
     | 
    
         
             
            - lib/flex_columns/active_record/base.rb
         
     | 
| 
       107 
107 
     | 
    
         
             
            - lib/flex_columns/contents/column_data.rb
         
     | 
| 
       108 
108 
     | 
    
         
             
            - lib/flex_columns/contents/flex_column_contents_base.rb
         
     | 
| 
      
 109 
     | 
    
         
            +
            - lib/flex_columns/definition/fake_column.rb
         
     | 
| 
       109 
110 
     | 
    
         
             
            - lib/flex_columns/definition/field_definition.rb
         
     | 
| 
       110 
111 
     | 
    
         
             
            - lib/flex_columns/definition/field_set.rb
         
     | 
| 
       111 
112 
     | 
    
         
             
            - lib/flex_columns/definition/flex_column_contents_class.rb
         
     | 
| 
         @@ -135,6 +136,7 @@ files: 
     | 
|
| 
       135 
136 
     | 
    
         
             
            - spec/flex_columns/unit/active_record/base_spec.rb
         
     | 
| 
       136 
137 
     | 
    
         
             
            - spec/flex_columns/unit/contents/column_data_spec.rb
         
     | 
| 
       137 
138 
     | 
    
         
             
            - spec/flex_columns/unit/contents/flex_column_contents_base_spec.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - spec/flex_columns/unit/definition/fake_column_spec.rb
         
     | 
| 
       138 
140 
     | 
    
         
             
            - spec/flex_columns/unit/definition/field_definition_spec.rb
         
     | 
| 
       139 
141 
     | 
    
         
             
            - spec/flex_columns/unit/definition/field_set_spec.rb
         
     | 
| 
       140 
142 
     | 
    
         
             
            - spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb
         
     | 
| 
         @@ -187,6 +189,7 @@ test_files: 
     | 
|
| 
       187 
189 
     | 
    
         
             
            - spec/flex_columns/unit/active_record/base_spec.rb
         
     | 
| 
       188 
190 
     | 
    
         
             
            - spec/flex_columns/unit/contents/column_data_spec.rb
         
     | 
| 
       189 
191 
     | 
    
         
             
            - spec/flex_columns/unit/contents/flex_column_contents_base_spec.rb
         
     | 
| 
      
 192 
     | 
    
         
            +
            - spec/flex_columns/unit/definition/fake_column_spec.rb
         
     | 
| 
       190 
193 
     | 
    
         
             
            - spec/flex_columns/unit/definition/field_definition_spec.rb
         
     | 
| 
       191 
194 
     | 
    
         
             
            - spec/flex_columns/unit/definition/field_set_spec.rb
         
     | 
| 
       192 
195 
     | 
    
         
             
            - spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb
         
     |