extjs-mvc 0.3.4 → 0.3.5
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.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/extjs-mvc.rb +2 -0
- data/lib/model/active_record.rb +11 -15
- data/lib/model/base.rb +108 -47
- data/lib/model/mongo_mapper.rb +9 -18
- data/test/model_test.rb +93 -13
- metadata +2 -2
    
        data/README.rdoc
    CHANGED
    
    | @@ -62,7 +62,7 @@ E.g. with the following definition: | |
| 62 62 | 
             
                class User < ActiveRecord::Base
         | 
| 63 63 | 
             
                  include ExtJS::Model
         | 
| 64 64 |  | 
| 65 | 
            -
                  extjs_fieldset :grid, [:name, :description, :company => [:name, :description]]
         | 
| 65 | 
            +
                  extjs_fieldset :grid, fields => [:name, :description, :company => [:name, :description]]
         | 
| 66 66 | 
             
                  extjs_fieldset :combo, [:full_name]
         | 
| 67 67 |  | 
| 68 68 | 
             
                  def full_name
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.3. | 
| 1 | 
            +
            0.3.5
         | 
    
        data/lib/extjs-mvc.rb
    CHANGED
    
    | @@ -16,6 +16,8 @@ module ExtJS | |
| 16 16 | 
             
                    require 'model/data_mapper'
         | 
| 17 17 | 
             
                  elsif defined?(MongoMapper)
         | 
| 18 18 | 
             
                    require 'model/mongo_mapper'
         | 
| 19 | 
            +
                  else
         | 
| 20 | 
            +
                    raise StandardError.new("extjs-mvc could not detect an ORM framework.  Be sure to include your ORM framework before initializing extjs-mvc Gem.")
         | 
| 19 21 | 
             
                  end
         | 
| 20 22 |  | 
| 21 23 | 
             
                  # Rails-style Array#extract_options! used heavily
         | 
    
        data/lib/model/active_record.rb
    CHANGED
    
    | @@ -68,21 +68,17 @@ module ExtJS | |
| 68 68 | 
             
                  # @return {Array}
         | 
| 69 69 | 
             
                  #
         | 
| 70 70 | 
             
                  def extjs_associations
         | 
| 71 | 
            -
                     | 
| 72 | 
            -
                       | 
| 73 | 
            -
                       | 
| 74 | 
            -
                         | 
| 75 | 
            -
                        type  | 
| 76 | 
            -
                         | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
                        }
         | 
| 83 | 
            -
                      end
         | 
| 84 | 
            -
                    #end        
         | 
| 85 | 
            -
                    extjs_associations
         | 
| 71 | 
            +
                    @extjs_associations ||= self.reflections.inject({}) do |memo, (key, assn)|
         | 
| 72 | 
            +
                      type = (assn.macro === :has_many || assn.macro === :has_and_belongs_to_many) ? :many : assn.macro
         | 
| 73 | 
            +
                      memo[key.to_sym] = {
         | 
| 74 | 
            +
                        :name => key.to_sym, 
         | 
| 75 | 
            +
                        :type => type, 
         | 
| 76 | 
            +
                        :class => assn.options[:polymorphic] ? nil : assn.class_name.constantize,
         | 
| 77 | 
            +
                        :foreign_key => assn.association_foreign_key.to_sym,
         | 
| 78 | 
            +
                        :is_polymorphic => !!assn.options[:polymorphic]
         | 
| 79 | 
            +
                      }
         | 
| 80 | 
            +
                      memo
         | 
| 81 | 
            +
                    end
         | 
| 86 82 | 
             
                  end
         | 
| 87 83 | 
             
                end
         | 
| 88 84 | 
             
              end
         | 
    
        data/lib/model/base.rb
    CHANGED
    
    | @@ -21,23 +21,40 @@ module ExtJS | |
| 21 21 |  | 
| 22 22 | 
             
                  ##
         | 
| 23 23 | 
             
                  # Converts a model instance to a record compatible with ExtJS
         | 
| 24 | 
            -
                  # @params {Mixed} params A list of fields to use instead of this Class's extjs_record_fields
         | 
| 25 24 | 
             
                  #
         | 
| 25 | 
            +
                  # The first parameter should be the fieldset for which the record will be returned.
         | 
| 26 | 
            +
                  # If no parameter is provided, then the default fieldset will be choosen
         | 
| 27 | 
            +
                  # Alternativly the first parameter can be a Hash with a :fields member to directly specify
         | 
| 28 | 
            +
                  # the fields to use for the record.
         | 
| 29 | 
            +
                  #
         | 
| 30 | 
            +
                  # All these are valid calls:
         | 
| 31 | 
            +
                  #
         | 
| 32 | 
            +
                  #  user.to_record             # returns record for :default fieldset 
         | 
| 33 | 
            +
                  #                             # (fieldset is autmatically defined, if not set)
         | 
| 34 | 
            +
                  #
         | 
| 35 | 
            +
                  #  user.to_record :fieldset   # returns record for :fieldset fieldset
         | 
| 36 | 
            +
                  #                             # (fieldset is autmatically defined, if not set)
         | 
| 37 | 
            +
                  #
         | 
| 38 | 
            +
                  #  user.to_record :fields => [:id, :password]
         | 
| 39 | 
            +
                  #                             # returns record for the fields 'id' and 'password'
         | 
| 40 | 
            +
                  # 
         | 
| 41 | 
            +
                  # For even more valid options for this method (which all should not be neccessary to use)
         | 
| 42 | 
            +
                  # have a look at ExtJS::Model::Util.extract_fieldset_and_options
         | 
| 26 43 | 
             
                  def to_record(*params)
         | 
| 27 | 
            -
                    fieldset,  | 
| 44 | 
            +
                    fieldset, options = Util.extract_fieldset_and_options params
         | 
| 28 45 |  | 
| 29 46 | 
             
                    fields = []
         | 
| 30 | 
            -
                    if  | 
| 47 | 
            +
                    if options[:fields].empty?
         | 
| 31 48 | 
             
                      fields = self.class.extjs_get_fields_for_fieldset(fieldset)
         | 
| 32 49 | 
             
                    else
         | 
| 33 | 
            -
                      fields = self.class.process_fields(* | 
| 50 | 
            +
                      fields = self.class.process_fields(*options[:fields])
         | 
| 34 51 | 
             
                    end
         | 
| 35 52 |  | 
| 36 53 | 
             
                    assns   = self.class.extjs_associations
         | 
| 37 54 | 
             
                    pk      = self.class.extjs_primary_key
         | 
| 38 55 |  | 
| 39 56 | 
             
                    # build the initial field data-hash
         | 
| 40 | 
            -
                    data    =  | 
| 57 | 
            +
                    data    = {pk => self.send(pk)}
         | 
| 41 58 |  | 
| 42 59 | 
             
                    fields.each do |field|
         | 
| 43 60 | 
             
                      next if data.has_key? field[:name] # already processed (e.g. explicit mentioning of :id)
         | 
| @@ -45,25 +62,34 @@ module ExtJS | |
| 45 62 | 
             
                      value = nil
         | 
| 46 63 | 
             
                      if association_reflection = assns[field[:name]] # if field is an association
         | 
| 47 64 | 
             
                        association = self.send(field[:name])
         | 
| 65 | 
            +
                        
         | 
| 66 | 
            +
                        # skip this association if we already visited it
         | 
| 67 | 
            +
                        # otherwise we could end up in a cyclic reference
         | 
| 68 | 
            +
                        next if options[:visited_classes].include? association.class
         | 
| 69 | 
            +
                        
         | 
| 48 70 | 
             
                        case association_reflection[:type]
         | 
| 49 | 
            -
                        when :belongs_to
         | 
| 71 | 
            +
                        when :belongs_to, :has_one
         | 
| 50 72 | 
             
                          if association.respond_to? :to_record
         | 
| 51 73 | 
             
                            assn_fields = field[:fields]
         | 
| 52 74 | 
             
                            if assn_fields.nil?
         | 
| 53 75 | 
             
                              assn_fields = association.class.extjs_get_fields_for_fieldset(field.fetch(:fieldset, fieldset))
         | 
| 54 76 | 
             
                            end
         | 
| 55 | 
            -
                             | 
| 77 | 
            +
                            
         | 
| 78 | 
            +
                            value = association.to_record :fields => assn_fields,
         | 
| 79 | 
            +
                              :visited_classes => options[:visited_classes] + [self.class]
         | 
| 56 80 | 
             
                          else
         | 
| 57 81 | 
             
                            value = {}
         | 
| 58 82 | 
             
                            (field[:fields]||[]).each do |sub_field|
         | 
| 59 83 | 
             
                              value[sub_field[:name]] = association.send(sub_field[:name]) if association.respond_to? sub_field[:name]
         | 
| 60 84 | 
             
                            end
         | 
| 61 85 | 
             
                          end
         | 
| 62 | 
            -
                           | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
                             | 
| 66 | 
            -
             | 
| 86 | 
            +
                          if association_reflection[:type] == :belongs_to
         | 
| 87 | 
            +
                            # Append associations foreign_key to data
         | 
| 88 | 
            +
                            data[association_reflection[:foreign_key]] = self.send(association_reflection[:foreign_key])
         | 
| 89 | 
            +
                            if association_reflection[:is_polymorphic]
         | 
| 90 | 
            +
                              foreign_type = self.class.extjs_polymorphic_type(association_reflection[:foreign_key])
         | 
| 91 | 
            +
                              data[foreign_type] = self.send(foreign_type)
         | 
| 92 | 
            +
                            end
         | 
| 67 93 | 
             
                          end
         | 
| 68 94 | 
             
                        when :many
         | 
| 69 95 | 
             
                          value = association.collect { |r| r.to_record }  # use carefully, can get HUGE
         | 
| @@ -76,15 +102,6 @@ module ExtJS | |
| 76 102 | 
             
                    end
         | 
| 77 103 | 
             
                    data
         | 
| 78 104 | 
             
                  end
         | 
| 79 | 
            -
                  
         | 
| 80 | 
            -
                  ##
         | 
| 81 | 
            -
                  # prepares the initial data-hash.  Had to implement this to fix a MongoMapper issue where pk
         | 
| 82 | 
            -
                  # is an Object.  Messed things up when converting to JSON.  Perhaps a better way is possible.
         | 
| 83 | 
            -
                  # Any adapter can override this but typical relational dbs with Integer pks won't need to.
         | 
| 84 | 
            -
                  #
         | 
| 85 | 
            -
                  def extjs_prepare_data(pk)
         | 
| 86 | 
            -
                    {pk => self.send(pk)}
         | 
| 87 | 
            -
                  end
         | 
| 88 105 | 
             
                end
         | 
| 89 106 |  | 
| 90 107 | 
             
                ##
         | 
| @@ -95,12 +112,31 @@ module ExtJS | |
| 95 112 | 
             
                  # render AR columns to Ext.data.Record.create format
         | 
| 96 113 | 
             
                  # eg: {name:'foo', type: 'string'}
         | 
| 97 114 | 
             
                  #
         | 
| 98 | 
            -
                   | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 115 | 
            +
                  # The first parameter should be the fieldset for which the record definition will be returned.
         | 
| 116 | 
            +
                  # If no parameter is provided, then the default fieldset will be choosen
         | 
| 117 | 
            +
                  # Alternativly the first parameter can be a Hash with a :fields member to directly specify
         | 
| 118 | 
            +
                  # the fields to use for the record config.
         | 
| 119 | 
            +
                  #
         | 
| 120 | 
            +
                  # All these are valid calls:
         | 
| 121 | 
            +
                  #
         | 
| 122 | 
            +
                  #  User.extjs_record             # returns record config for :default fieldset 
         | 
| 123 | 
            +
                  #                                # (fieldset is autmatically defined, if not set)
         | 
| 124 | 
            +
                  #
         | 
| 125 | 
            +
                  #  User.extjs_record :fieldset   # returns record config for :fieldset fieldset
         | 
| 126 | 
            +
                  #                                # (fieldset is autmatically defined, if not set)
         | 
| 127 | 
            +
                  #
         | 
| 128 | 
            +
                  #  User.extjs_record :fields => [:id, :password]
         | 
| 129 | 
            +
                  #                                # returns record config for the fields 'id' and 'password'
         | 
| 130 | 
            +
                  # 
         | 
| 131 | 
            +
                  # For even more valid options for this method (which all should not be neccessary to use)
         | 
| 132 | 
            +
                  # have a look at ExtJS::Model::Util.extract_fieldset_and_options
         | 
| 133 | 
            +
                  def extjs_record(*params)
         | 
| 134 | 
            +
                    fieldset, options = Util.extract_fieldset_and_options params
         | 
| 135 | 
            +
                    
         | 
| 136 | 
            +
                    if options[:fields].empty?
         | 
| 101 137 | 
             
                      fields = self.extjs_get_fields_for_fieldset(fieldset)
         | 
| 102 138 | 
             
                    else
         | 
| 103 | 
            -
                      fields = self.process_fields(*fields)
         | 
| 139 | 
            +
                      fields = self.process_fields(*options[:fields])
         | 
| 104 140 | 
             
                    end
         | 
| 105 141 |  | 
| 106 142 | 
             
                    associations  = self.extjs_associations
         | 
| @@ -109,17 +145,23 @@ module ExtJS | |
| 109 145 | 
             
                    rs            = []
         | 
| 110 146 |  | 
| 111 147 | 
             
                    fields.each do |field|
         | 
| 148 | 
            +
             | 
| 112 149 | 
             
                      field = Marshal.load(Marshal.dump(field)) # making a deep copy
         | 
| 113 150 |  | 
| 114 151 | 
             
                      if col = columns[field[:name]] # <-- column on this model                
         | 
| 115 152 | 
             
                        rs << self.extjs_field(field, col)      
         | 
| 116 153 | 
             
                      elsif assn = associations[field[:name]]
         | 
| 154 | 
            +
                        # skip this association if we already visited it
         | 
| 155 | 
            +
                        # otherwise we could end up in a cyclic reference
         | 
| 156 | 
            +
                        next if options[:visited_classes].include? assn[:class]
         | 
| 157 | 
            +
                        
         | 
| 117 158 | 
             
                        assn_fields = field[:fields]
         | 
| 118 159 | 
             
                        if assn[:class].respond_to?(:extjs_record)  # <-- exec extjs_record on assn Model.
         | 
| 119 160 | 
             
                          if assn_fields.nil?
         | 
| 120 161 | 
             
                            assn_fields = assn[:class].extjs_get_fields_for_fieldset(field.fetch(:fieldset, fieldset))
         | 
| 121 162 | 
             
                          end
         | 
| 122 | 
            -
                           | 
| 163 | 
            +
                          
         | 
| 164 | 
            +
                          record = assn[:class].extjs_record(field.fetch(:fieldset, fieldset), { :visited_classes => options[:visited_classes] + [self], :fields => assn_fields})
         | 
| 123 165 | 
             
                          rs.concat(record[:fields].collect { |assn_field| 
         | 
| 124 166 | 
             
                            self.extjs_field(assn_field, :parent_trail => field[:name], :mapping => field[:name], :allowBlank => true) # <-- allowBlank on associated data?
         | 
| 125 167 | 
             
                          })
         | 
| @@ -170,12 +212,9 @@ module ExtJS | |
| 170 212 | 
             
                  # end
         | 
| 171 213 | 
             
                  #
         | 
| 172 214 | 
             
                  def extjs_fieldset(*params)
         | 
| 173 | 
            -
                    fieldset,  | 
| 174 | 
            -
                    # creates a method storing the fieldset-to-field association
         | 
| 175 | 
            -
                    # using a method and not an class-level variable because the latter
         | 
| 176 | 
            -
                    # is bogus when we deal with inheritance
         | 
| 215 | 
            +
                    fieldset, options = Util.extract_fieldset_and_options params
         | 
| 177 216 | 
             
                    var_name = :"@extjs_fieldsets__#{fieldset}"
         | 
| 178 | 
            -
                    self.instance_variable_set( var_name, self.process_fields(* | 
| 217 | 
            +
                    self.instance_variable_set( var_name, self.process_fields(*options[:fields]) )
         | 
| 179 218 | 
             
                  end
         | 
| 180 219 |  | 
| 181 220 | 
             
                  def extjs_get_fields_for_fieldset(fieldset)
         | 
| @@ -194,7 +233,9 @@ module ExtJS | |
| 194 233 | 
             
                  # shortcut to define the default fieldset. For backwards-compatibility.
         | 
| 195 234 | 
             
                  #
         | 
| 196 235 | 
             
                  def extjs_fields(*params)
         | 
| 197 | 
            -
                    self.extjs_fieldset(:default,  | 
| 236 | 
            +
                    self.extjs_fieldset(:default, {
         | 
| 237 | 
            +
                      :fields => params
         | 
| 238 | 
            +
                    })
         | 
| 198 239 | 
             
                  end
         | 
| 199 240 |  | 
| 200 241 | 
             
                  ##
         | 
| @@ -229,9 +270,10 @@ module ExtJS | |
| 229 270 | 
             
                        elsif f.has_key?(:name) # already a valid Hash, just copy it over
         | 
| 230 271 | 
             
                          fields << f
         | 
| 231 272 | 
             
                        else
         | 
| 232 | 
            -
                          raise ArgumentError, "encountered a Hash that I don't know  | 
| 273 | 
            +
                          raise ArgumentError, "encountered a Hash that I don't know anything to do with `#{f.inspect}:#{f.class}`"
         | 
| 233 274 | 
             
                        end
         | 
| 234 275 | 
             
                      else # should be a String or Symbol
         | 
| 276 | 
            +
                        raise ArgumentError, "encountered a fields Array that I don't understand: #{params.inspect} -- `#{f.inspect}:#{f.class}` is not a Symbol or String" unless f.is_a?(Symbol) || f.is_a?(String)
         | 
| 235 277 | 
             
                        fields << {:name => f.to_sym}
         | 
| 236 278 | 
             
                      end
         | 
| 237 279 | 
             
                    end
         | 
| @@ -239,20 +281,6 @@ module ExtJS | |
| 239 281 | 
             
                    fields
         | 
| 240 282 | 
             
                  end
         | 
| 241 283 |  | 
| 242 | 
            -
                  ##
         | 
| 243 | 
            -
                  # returns the fieldset from the arguments. 
         | 
| 244 | 
            -
                  # @return [{Symbol}, Array]
         | 
| 245 | 
            -
                  def extjs_extract_fieldset! arguments
         | 
| 246 | 
            -
                    fieldset = :default
         | 
| 247 | 
            -
                    if arguments.size > 1 && arguments[0].is_a?(Symbol) && arguments[1].is_a?(Array)
         | 
| 248 | 
            -
                      fieldset = arguments.shift
         | 
| 249 | 
            -
                      arguments = arguments[0]
         | 
| 250 | 
            -
                    elsif arguments.size == 1 && arguments[0].is_a?(Symbol)
         | 
| 251 | 
            -
                      fieldset = arguments.shift
         | 
| 252 | 
            -
                    end
         | 
| 253 | 
            -
                    [fieldset, arguments]
         | 
| 254 | 
            -
                  end
         | 
| 255 | 
            -
                  
         | 
| 256 284 | 
             
                  ##
         | 
| 257 285 | 
             
                  # Render a column-config object
         | 
| 258 286 | 
             
                  # @param {Hash/Column} field Field-configuration Hash, probably has :name already set and possibly Ext.data.Field options.
         | 
| @@ -302,6 +330,39 @@ module ExtJS | |
| 302 330 | 
             
                  #   @extjs_used_associations
         | 
| 303 331 | 
             
                  # end
         | 
| 304 332 | 
             
                end
         | 
| 333 | 
            +
                
         | 
| 334 | 
            +
                module Util
         | 
| 335 | 
            +
                  
         | 
| 336 | 
            +
                  ##
         | 
| 337 | 
            +
                  # returns the fieldset from the arguments and normalizes the options. 
         | 
| 338 | 
            +
                  # @return [{Symbol}, {Hash}]
         | 
| 339 | 
            +
                  def self.extract_fieldset_and_options arguments
         | 
| 340 | 
            +
                    orig_args = arguments
         | 
| 341 | 
            +
                    fieldset = :default
         | 
| 342 | 
            +
                    options = { # default options
         | 
| 343 | 
            +
                      :visited_classes => [],
         | 
| 344 | 
            +
                      :fields => []
         | 
| 345 | 
            +
                    }
         | 
| 346 | 
            +
                    if arguments.size > 2 || (arguments.size == 2 && !arguments[0].is_a?(Symbol))
         | 
| 347 | 
            +
                      raise ArgumentError, "Don't know how to handle #{arguments.inspect}"
         | 
| 348 | 
            +
                    elsif arguments.size == 2 && arguments[0].is_a?(Symbol)
         | 
| 349 | 
            +
                      fieldset = arguments.shift
         | 
| 350 | 
            +
                      if arguments[0].is_a?(Array)
         | 
| 351 | 
            +
                        options.update({
         | 
| 352 | 
            +
                          :fields => arguments[0]
         | 
| 353 | 
            +
                        })
         | 
| 354 | 
            +
                      elsif arguments[0].is_a?(Hash)
         | 
| 355 | 
            +
                        options.update(arguments[0])
         | 
| 356 | 
            +
                      end
         | 
| 357 | 
            +
                    elsif arguments.size == 1 && arguments[0].is_a?(Symbol)
         | 
| 358 | 
            +
                      fieldset = arguments.shift
         | 
| 359 | 
            +
                    elsif arguments.size == 1 && arguments[0].is_a?(Hash)
         | 
| 360 | 
            +
                      fieldset = arguments[0].delete(:fieldset) || :default
         | 
| 361 | 
            +
                      options.update(arguments[0])
         | 
| 362 | 
            +
                    end
         | 
| 363 | 
            +
                    [fieldset, options]
         | 
| 364 | 
            +
                  end
         | 
| 365 | 
            +
                end
         | 
| 305 366 | 
             
              end
         | 
| 306 367 | 
             
            end
         | 
| 307 368 |  | 
    
        data/lib/model/mongo_mapper.rb
    CHANGED
    
    | @@ -4,12 +4,6 @@ | |
| 4 4 |  | 
| 5 5 | 
             
            module ExtJS
         | 
| 6 6 | 
             
              module Model
         | 
| 7 | 
            -
                module InstanceMethods
         | 
| 8 | 
            -
                  def extjs_prepare_data(pk)
         | 
| 9 | 
            -
                    {pk => self.send(pk).to_s}
         | 
| 10 | 
            -
                  end
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
                
         | 
| 13 7 | 
             
                ##
         | 
| 14 8 | 
             
                # ClassMethods
         | 
| 15 9 | 
             
                #
         | 
| @@ -28,19 +22,16 @@ module ExtJS | |
| 28 22 | 
             
                  end
         | 
| 29 23 |  | 
| 30 24 | 
             
                  def extjs_associations
         | 
| 31 | 
            -
                     | 
| 32 | 
            -
                       | 
| 33 | 
            -
             | 
| 34 | 
            -
                         | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                        }
         | 
| 41 | 
            -
                      end
         | 
| 25 | 
            +
                    @extjs_associations ||= self.associations.inject({}) do |memo, (key, assn)|
         | 
| 26 | 
            +
                      memo[key.to_sym] = {
         | 
| 27 | 
            +
                        :name => key.to_sym,
         | 
| 28 | 
            +
                        :type => assn.type,
         | 
| 29 | 
            +
                        :class => assn.class_name.constantize,
         | 
| 30 | 
            +
                        :foreign_key => assn.foreign_key,
         | 
| 31 | 
            +
                        :is_polymorphic => false
         | 
| 32 | 
            +
                      }
         | 
| 33 | 
            +
                      memo
         | 
| 42 34 | 
             
                    end
         | 
| 43 | 
            -
                    @extjs_associations
         | 
| 44 35 | 
             
                  end
         | 
| 45 36 |  | 
| 46 37 | 
             
                  def extjs_type(col)
         | 
    
        data/test/model_test.rb
    CHANGED
    
    | @@ -166,6 +166,48 @@ class ModelTest < Test::Unit::TestCase | |
| 166 166 | 
             
                end
         | 
| 167 167 | 
             
              end
         | 
| 168 168 |  | 
| 169 | 
            +
              context "Person with User association (has_one relationship)" do
         | 
| 170 | 
            +
                setup do
         | 
| 171 | 
            +
                  clean_all
         | 
| 172 | 
            +
                  User.extjs_fields(:id, :password)
         | 
| 173 | 
            +
                  Person.extjs_fields(:id, :user)
         | 
| 174 | 
            +
                end
         | 
| 175 | 
            +
                should "produce a valid store config" do
         | 
| 176 | 
            +
                  fields = Person.extjs_record[:fields]
         | 
| 177 | 
            +
                  assert_array_has_item(fields, 'has id') {|f| f[:name] === "id" }
         | 
| 178 | 
            +
                  assert_array_has_item(fields, 'has user_id') {|f| f[:name] === "user_id" and f[:mapping] == 'user.id' }
         | 
| 179 | 
            +
                  assert_array_has_item(fields, 'has user_password') {|f| f[:name] === "user_password"and f[:mapping] == 'user.password' }
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
                should "produce a valid to_record record" do
         | 
| 182 | 
            +
                  person = Person.create!(:first => 'first', :last => 'last', :email => 'email')
         | 
| 183 | 
            +
                  user = User.create!(:person_id => person.id, :password => 'password')
         | 
| 184 | 
            +
                  record = person.reload.to_record
         | 
| 185 | 
            +
                  assert_equal(person.id, record[:id])
         | 
| 186 | 
            +
                  assert_equal(user.id, record[:user][:id])
         | 
| 187 | 
            +
                  assert_equal('password', record[:user][:password])
         | 
| 188 | 
            +
                end
         | 
| 189 | 
            +
              end
         | 
| 190 | 
            +
              
         | 
| 191 | 
            +
              context "Person with User association (has_one/belongs_to relationship) cyclic reference" do
         | 
| 192 | 
            +
                setup do
         | 
| 193 | 
            +
                  clean_all
         | 
| 194 | 
            +
                  User.extjs_fields(:id, :person)
         | 
| 195 | 
            +
                  Person.extjs_fields(:id, :user)
         | 
| 196 | 
            +
                end
         | 
| 197 | 
            +
                should "produce a valid store config for Person" do
         | 
| 198 | 
            +
                  fields = Person.extjs_record[:fields]
         | 
| 199 | 
            +
                  assert_array_has_item(fields, 'has id') {|f| f[:name] === "id" }
         | 
| 200 | 
            +
                  assert_array_has_item(fields, 'has user_id') {|f| f[:name] === "user_id" and f[:mapping] == 'user.id' }
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
                should "produce a valid to_record record for Person" do
         | 
| 203 | 
            +
                  person = Person.create!(:first => 'first', :last => 'last', :email => 'email')
         | 
| 204 | 
            +
                  user = User.create!(:person_id => person.id, :password => 'password')
         | 
| 205 | 
            +
                  record = person.reload.to_record
         | 
| 206 | 
            +
                  assert_equal(person.id, record[:id])
         | 
| 207 | 
            +
                  assert_equal(user.id, record[:user][:id])
         | 
| 208 | 
            +
                end
         | 
| 209 | 
            +
              end
         | 
| 210 | 
            +
              
         | 
| 169 211 | 
             
              context "Fields should render with correct, ExtJS-compatible data-types" do
         | 
| 170 212 | 
             
                setup do
         | 
| 171 213 | 
             
                  clean_all
         | 
| @@ -204,7 +246,7 @@ class ModelTest < Test::Unit::TestCase | |
| 204 246 | 
             
                end
         | 
| 205 247 | 
             
              end
         | 
| 206 248 |  | 
| 207 | 
            -
              context "polymorphic  | 
| 249 | 
            +
              context "polymorphic associations" do
         | 
| 208 250 | 
             
                setup do
         | 
| 209 251 | 
             
                  clean_all
         | 
| 210 252 | 
             
                end
         | 
| @@ -220,7 +262,7 @@ class ModelTest < Test::Unit::TestCase | |
| 220 262 | 
             
                  assert_array_has_item(fields, 'addressable_type') {|f| f[:name] === 'addressable_type' && !f[:mapping] }
         | 
| 221 263 | 
             
                end
         | 
| 222 264 |  | 
| 223 | 
            -
                should "create the right store config when including members of the  | 
| 265 | 
            +
                should "create the right store config when including members of the polymorphic association" do
         | 
| 224 266 | 
             
                  Address.extjs_fields :street, :addressable => [:name]
         | 
| 225 267 | 
             
                  fields = Address.extjs_record[:fields]
         | 
| 226 268 | 
             
                  assert_array_has_item(fields, "has addressable_name") {|f| f[:name] === 'addressable_name' && f[:mapping] === 'addressable.name'}
         | 
| @@ -246,13 +288,13 @@ class ModelTest < Test::Unit::TestCase | |
| 246 288 | 
             
                  clean_all
         | 
| 247 289 | 
             
                end
         | 
| 248 290 |  | 
| 249 | 
            -
                should "fieldsets should be accessible from  | 
| 291 | 
            +
                should "fieldsets should be accessible from descendants" do
         | 
| 250 292 | 
             
                  Location.extjs_fieldset :on_location, [:street]
         | 
| 251 293 | 
             
                  fields = House.extjs_record(:on_location)[:fields]
         | 
| 252 294 | 
             
                  assert_array_has_item(fields, 'has street') {|f| f[:name] === 'street' }
         | 
| 253 295 | 
             
                  assert_array_has_not_item(fields, 'has name') {|f| f[:name] === 'name' }
         | 
| 254 296 | 
             
                end
         | 
| 255 | 
            -
                should "fieldsets should be overrideable from  | 
| 297 | 
            +
                should "fieldsets should be overrideable from descendants" do
         | 
| 256 298 | 
             
                  Location.extjs_fieldset :override, [:street]
         | 
| 257 299 | 
             
                  House.extjs_fieldset :override, [:name]
         | 
| 258 300 | 
             
                  fields = House.extjs_record(:override)[:fields]
         | 
| @@ -261,11 +303,11 @@ class ModelTest < Test::Unit::TestCase | |
| 261 303 | 
             
                end
         | 
| 262 304 | 
             
              end
         | 
| 263 305 |  | 
| 264 | 
            -
              context "ExtJS::Model:: | 
| 265 | 
            -
             | 
| 266 | 
            -
                context "#extjs_extract_fieldset! default" do
         | 
| 306 | 
            +
              context "ExtJS::Model::Util" do
         | 
| 307 | 
            +
                context "#extract_fieldset_and_options default" do
         | 
| 267 308 | 
             
                  setup do
         | 
| 268 | 
            -
                    @fieldset, @ | 
| 309 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options [:fields => [:one, :two, :three]]
         | 
| 310 | 
            +
                    @fields = @options[:fields]
         | 
| 269 311 | 
             
                  end
         | 
| 270 312 | 
             
                  should "return :default when no fieldset provided" do
         | 
| 271 313 | 
             
                    assert_equal(:'default', @fieldset)
         | 
| @@ -275,9 +317,10 @@ class ModelTest < Test::Unit::TestCase | |
| 275 317 | 
             
                  end
         | 
| 276 318 | 
             
                end
         | 
| 277 319 |  | 
| 278 | 
            -
                context "# | 
| 320 | 
            +
                context "#extract_fieldset_and_options with explicit fieldset definition and array with fields" do
         | 
| 279 321 | 
             
                  setup do
         | 
| 280 | 
            -
                    @fieldset, @ | 
| 322 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options [:explicit, [:one, :two, :three]]
         | 
| 323 | 
            +
                    @fields = @options[:fields]
         | 
| 281 324 | 
             
                  end
         | 
| 282 325 | 
             
                  should "return :default when no fieldset provided" do
         | 
| 283 326 | 
             
                    assert_equal(:'explicit', @fieldset)
         | 
| @@ -287,18 +330,55 @@ class ModelTest < Test::Unit::TestCase | |
| 287 330 | 
             
                  end
         | 
| 288 331 | 
             
                end
         | 
| 289 332 |  | 
| 290 | 
            -
                context "# | 
| 333 | 
            +
                context "#extract_fieldset_and_options with explicit fieldset definition and hash with fields" do
         | 
| 334 | 
            +
                  setup do
         | 
| 335 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options [:explicit, {:fields => [:one, :two, :three]}]
         | 
| 336 | 
            +
                    @fields = @options[:fields]
         | 
| 337 | 
            +
                  end
         | 
| 338 | 
            +
                  should "return :default when no fieldset provided" do
         | 
| 339 | 
            +
                    assert_equal(:'explicit', @fieldset)
         | 
| 340 | 
            +
                  end
         | 
| 341 | 
            +
                  should "not alter the fields array" do
         | 
| 342 | 
            +
                    assert_equal([:one, :two, :three], @fields)
         | 
| 343 | 
            +
                  end
         | 
| 344 | 
            +
                end
         | 
| 345 | 
            +
                
         | 
| 346 | 
            +
                context "#extract_fieldset_and_options with only a hash" do
         | 
| 347 | 
            +
                  setup do
         | 
| 348 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options [{:fieldset => :explicit, :fields => [:one, :two, :three]}]
         | 
| 349 | 
            +
                    @fields = @options[:fields]
         | 
| 350 | 
            +
                  end
         | 
| 351 | 
            +
                  should "return :default when no fieldset provided" do
         | 
| 352 | 
            +
                    assert_equal(:'explicit', @fieldset)
         | 
| 353 | 
            +
                  end
         | 
| 354 | 
            +
                  should "not alter the fields array" do
         | 
| 355 | 
            +
                    assert_equal([:one, :two, :three], @fields)
         | 
| 356 | 
            +
                  end
         | 
| 357 | 
            +
                end
         | 
| 358 | 
            +
                
         | 
| 359 | 
            +
                context "#extract_fieldset_and_options edge cases" do
         | 
| 291 360 | 
             
                  should "called without arguments" do
         | 
| 292 | 
            -
                    @fieldset, @ | 
| 361 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options []
         | 
| 362 | 
            +
                    @fields = @options[:fields]
         | 
| 293 363 | 
             
                    assert_equal(:'default', @fieldset)
         | 
| 294 364 | 
             
                    assert_equal([], @fields)
         | 
| 295 365 | 
             
                  end
         | 
| 296 366 | 
             
                  should "called with only the fieldset and no field arguments" do
         | 
| 297 | 
            -
                    @fieldset, @ | 
| 367 | 
            +
                    @fieldset, @options = ExtJS::Model::Util.extract_fieldset_and_options [:explicit]
         | 
| 368 | 
            +
                    @fields = @options[:fields]
         | 
| 298 369 | 
             
                    assert_equal(:'explicit', @fieldset)
         | 
| 299 370 | 
             
                    assert_equal([], @fields)
         | 
| 300 371 | 
             
                  end
         | 
| 372 | 
            +
                  should "raise error when called with more than 2 arguments" do
         | 
| 373 | 
            +
                    assert_raise(ArgumentError) { ExtJS::Model::Util.extract_fieldset_and_options [:explicit, :some, {}] }
         | 
| 374 | 
            +
                  end
         | 
| 375 | 
            +
                  should "raise error when called with 2 arguments and the first one is no symbol" do
         | 
| 376 | 
            +
                    assert_raise(ArgumentError) { ExtJS::Model::Util.extract_fieldset_and_options [{ :fields => [] }, :explicit] }
         | 
| 377 | 
            +
                  end
         | 
| 301 378 | 
             
                end
         | 
| 379 | 
            +
              end
         | 
| 380 | 
            +
              
         | 
| 381 | 
            +
              context "ExtJS::Model::ClassMethods" do
         | 
| 302 382 |  | 
| 303 383 | 
             
                context "#process_fields" do
         | 
| 304 384 | 
             
                  should "handle a simple Array of Symbols" do
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: extjs-mvc
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0.3. | 
| 4 | 
            +
              version: 0.3.5
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Chris Scott
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2010-02- | 
| 12 | 
            +
            date: 2010-02-21 00:00:00 -05:00
         | 
| 13 13 | 
             
            default_executable: 
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         |