Module: Rack
- Defined in:
- lib/rack/core-data/version.rb,
lib/rack/core-data.rb
Defined Under Namespace
Modules: CoreData
Class Method Summary collapse
Class Method Details
.CoreData(xcdatamodel) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rack/core-data.rb', line 16 def self.CoreData(xcdatamodel) model = CoreData::DataModel.new(xcdatamodel) # Create each model class before implementing, in order to correctly set up relationships model.entities.each do |entity| klass = Rack::CoreData::Models.const_set(entity.name.capitalize, Class.new(Sequel::Model)) end app = Class.new(Sinatra::Base) do use Rack::PostBodyContentTypeParser before do content_type :json end helpers Sinatra::Param end model.entities.each do |entity| klass = Rack::CoreData::Models.const_get(entity.name.capitalize) klass.dataset = entity.name.downcase.pluralize.to_sym klass.class_eval do self.strict_param_setting = false self.raise_on_save_failure = false plugin :json_serializer, naked: true, include: [:url] plugin :schema plugin :validation_helpers def url "/#{self.class.table_name}/#{self[primary_key]}" end entity.relationships.each do |relationship| = {:class => Rack::CoreData::Models.const_get(relationship.destination.capitalize)} if relationship.to_many? one_to_many relationship.name.to_sym, else many_to_one relationship.name.to_sym, end end set_schema do primary_key :id entity.attributes.each do |attribute| next if attribute.transient? = { :null => attribute.optional?, :index => attribute.indexed?, :default => attribute.default_value } type = case attribute.type when "Integer 16" then :int2 when "Integer 32" then :int4 when "Integer 64" then :int8 when "Float" then :float4 when "Double" then :float8 when "Decimal" then :float8 when "Date" then :timestamp when "Boolean" then :boolean when "Binary" then :bytea else :varchar end column attribute.name.to_sym, type, end entity.relationships.each do |relationship| = { :index => true, :null => relationship.optional? } if not relationship.to_many? column "#{relationship.name}_id".to_sym, :integer, end end end if table_exists? missing_columns = schema.columns.reject{|c| columns.include?(c[:name])} db.alter_table table_name do missing_columns.each do || add_column .delete(:name), .delete(:type), end end else create_table end end klass.send :define_method, :validate do entity.attributes.each do |attribute| case attribute.type when "Integer 16", "Integer 32", "Integer 64" validates_integer attribute.name when "Float", "Double", "Decimal" validates_numeric attribute.name when "String" validates_min_length attribute.minimum_value, attribute.name if attribute.minimum_value validates_max_length attribute.maximum_value, attribute.name if attribute.maximum_value end end end app.class_eval do include Rack::CoreData::Models klass = Rack::CoreData::Models.const_get(entity.name.capitalize) disable :raise_errors, :show_exceptions get "/#{klass.table_name}/?" do if params[:page] or params[:per_page] param :page, Integer, default: 1, min: 1 param :per_page, Integer, default: 100, in: (1..100) { "#{klass.table_name}" => klass.limit(params[:per_page], (params[:page] - 1) * params[:per_page]), page: params[:page], total: klass.count }.to_json else param :limit, Integer, default: 100, in: (1..100) param :offset, Integer, default: 0, min: 0 { "#{klass.table_name}" => klass.limit(params[:limit], params[:offset]) }.to_json end end post "/#{klass.table_name}/?" do record = klass.new(params) if record.save status 201 {entity.name.downcase => record}.to_json else status 406 {errors: record.errors}.to_json end end get "/#{klass.table_name}/:id/?" do record = klass[params[:id]] or halt 404 {entity.name.downcase => record}.to_json end put "/#{klass.table_name}/:id/?" do record = klass[params[:id]] or halt 404 if record.update(params) status 200 {entity.name.downcase => record}.to_json else status 406 {errors: record.errors}.to_json end end delete "/#{klass.table_name}/:id/?" do record = klass[params[:id]] or halt 404 if record.destroy status 200 else status 406 {errors: record.errors}.to_json end end entity.relationships.each do |relationship| next unless relationship.to_many? get "/#{klass.table_name}/:id/#{relationship.name}/?" do {relationship.name => klass[params[:id]].send(relationship.name)}.to_json end end end end return app end |