spree_api 1.2.5 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/.rspec +1 -0
  2. data/app/controllers/spree/api/addresses_controller.rb +17 -0
  3. data/app/controllers/spree/api/base_controller.rb +111 -0
  4. data/app/controllers/spree/api/countries_controller.rb +14 -0
  5. data/app/controllers/spree/api/images_controller.rb +29 -0
  6. data/app/controllers/spree/api/line_items_controller.rb +38 -0
  7. data/app/controllers/spree/api/orders_controller.rb +81 -0
  8. data/app/controllers/spree/api/payments_controller.rb +75 -0
  9. data/app/controllers/spree/api/product_properties_controller.rb +61 -0
  10. data/app/controllers/spree/api/products_controller.rb +45 -0
  11. data/app/controllers/spree/api/return_authorizations_controller.rb +50 -0
  12. data/app/controllers/spree/api/shipments_controller.rb +41 -0
  13. data/app/controllers/spree/api/taxonomies_controller.rb +46 -0
  14. data/app/controllers/spree/api/taxons_controller.rb +49 -0
  15. data/app/controllers/spree/api/variants_controller.rb +71 -0
  16. data/app/controllers/spree/api/zones_controller.rb +43 -0
  17. data/app/helpers/spree/api/api_helpers.rb +0 -5
  18. data/app/overrides/api_admin_user_edit_form.rb +1 -1
  19. data/app/views/spree/admin/users/_api_fields.html.erb +26 -14
  20. data/app/views/spree/api/{v1/addresses/show.rabl → addresses/show.v1.rabl} +0 -0
  21. data/app/views/spree/api/{v1/countries/index.rabl → countries/index.v1.rabl} +0 -0
  22. data/app/views/spree/api/{v1/countries/show.rabl → countries/show.v1.rabl} +0 -0
  23. data/app/views/spree/api/{v1/errors/gateway_error.rabl → errors/gateway_error.v1.rabl} +0 -0
  24. data/app/views/spree/api/{v1/errors/invalid_api_key.rabl → errors/invalid_api_key.v1.rabl} +0 -0
  25. data/app/views/spree/api/{v1/errors/invalid_resource.rabl → errors/invalid_resource.v1.rabl} +0 -0
  26. data/app/views/spree/api/{v1/errors/must_specify_api_key.rabl → errors/must_specify_api_key.v1.rabl} +0 -0
  27. data/app/views/spree/api/{v1/errors/not_found.rabl → errors/not_found.v1.rabl} +0 -0
  28. data/app/views/spree/api/{v1/errors/unauthorized.rabl → errors/unauthorized.v1.rabl} +0 -0
  29. data/app/views/spree/api/{v1/images/show.rabl → images/show.v1.rabl} +0 -0
  30. data/app/views/spree/api/{v1/line_items/new.rabl → line_items/new.v1.rabl} +0 -0
  31. data/app/views/spree/api/{v1/line_items/show.rabl → line_items/show.v1.rabl} +1 -1
  32. data/app/views/spree/api/{v1/orders/address.rabl → orders/address.v1.rabl} +0 -0
  33. data/app/views/spree/api/{v1/orders/canceled.rabl → orders/canceled.v1.rabl} +0 -0
  34. data/app/views/spree/api/{v1/orders/cart.rabl → orders/cart.v1.rabl} +0 -0
  35. data/app/views/spree/api/{v1/orders/complete.rabl → orders/complete.v1.rabl} +0 -0
  36. data/app/views/spree/api/{v1/orders/could_not_transition.rabl → orders/could_not_transition.v1.rabl} +0 -0
  37. data/app/views/spree/api/{v1/orders/delivery.rabl → orders/delivery.v1.rabl} +0 -0
  38. data/app/views/spree/api/{v1/orders/index.rabl → orders/index.v1.rabl} +0 -0
  39. data/app/views/spree/api/{v1/orders/invalid_shipping_method.rabl → orders/invalid_shipping_method.v1.rabl} +0 -0
  40. data/app/views/spree/api/{v1/orders/payment.rabl → orders/payment.v1.rabl} +0 -0
  41. data/app/views/spree/api/{v1/orders/show.rabl → orders/show.v1.rabl} +6 -6
  42. data/app/views/spree/api/{v1/payments/credit_over_limit.rabl → payments/credit_over_limit.v1.rabl} +0 -0
  43. data/app/views/spree/api/{v1/payments/index.rabl → payments/index.v1.rabl} +0 -0
  44. data/app/views/spree/api/{v1/payments/new.rabl → payments/new.v1.rabl} +0 -0
  45. data/app/views/spree/api/{v1/payments/show.rabl → payments/show.v1.rabl} +0 -0
  46. data/app/views/spree/api/{v1/product_properties/index.rabl → product_properties/index.v1.rabl} +0 -0
  47. data/app/views/spree/api/{v1/product_properties/new.rabl → product_properties/new.v1.rabl} +0 -0
  48. data/app/views/spree/api/{v1/product_properties/show.rabl → product_properties/show.v1.rabl} +0 -0
  49. data/app/views/spree/api/{v1/products/index.rabl → products/index.v1.rabl} +1 -2
  50. data/app/views/spree/api/{v1/products/new.rabl → products/new.v1.rabl} +0 -0
  51. data/app/views/spree/api/{v1/products/product.rabl → products/product.v1.rabl} +0 -0
  52. data/app/views/spree/api/{v1/products/show.rabl → products/show.v1.rabl} +1 -1
  53. data/app/views/spree/api/{v1/return_authorizations/index.rabl → return_authorizations/index.v1.rabl} +0 -0
  54. data/app/views/spree/api/{v1/return_authorizations/new.rabl → return_authorizations/new.v1.rabl} +0 -0
  55. data/app/views/spree/api/{v1/return_authorizations/show.rabl → return_authorizations/show.v1.rabl} +0 -0
  56. data/app/views/spree/api/{v1/shipments/cannot_ready_shipment.rabl → shipments/cannot_ready_shipment.v1.rabl} +0 -0
  57. data/app/views/spree/api/{v1/shipments/show.rabl → shipments/show.v1.rabl} +0 -0
  58. data/app/views/spree/api/{v1/taxonomies/index.rabl → taxonomies/index.v1.rabl} +1 -1
  59. data/app/views/spree/api/{v1/taxonomies/nested.rabl → taxonomies/nested.v1.rabl} +1 -1
  60. data/app/views/spree/api/{v1/taxonomies/new.rabl → taxonomies/new.v1.rabl} +0 -0
  61. data/app/views/spree/api/{v1/taxonomies/show.rabl → taxonomies/show.v1.rabl} +1 -1
  62. data/app/views/spree/api/{v1/taxons/index.rabl → taxons/index.v1.rabl} +1 -1
  63. data/app/views/spree/api/{v1/taxons/new.rabl → taxons/new.v1.rabl} +0 -0
  64. data/app/views/spree/api/{v1/taxons/show.rabl → taxons/show.v1.rabl} +0 -0
  65. data/app/views/spree/api/{v1/taxons/taxons.rabl → taxons/taxons.v1.rabl} +1 -1
  66. data/app/views/spree/api/{v1/variants/index.rabl → variants/index.v1.rabl} +0 -0
  67. data/app/views/spree/api/{v1/variants/new.rabl → variants/new.v1.rabl} +0 -0
  68. data/app/views/spree/api/{v1/variants/show.rabl → variants/show.v1.rabl} +1 -1
  69. data/app/views/spree/api/{v1/variants/variant.rabl → variants/variant.v1.rabl} +0 -0
  70. data/app/views/spree/api/{v1/zones/index.rabl → zones/index.v1.rabl} +1 -1
  71. data/app/views/spree/api/{v1/zones/show.rabl → zones/show.v1.rabl} +0 -0
  72. data/config/initializers/metal_load_paths.rb +1 -1
  73. data/config/routes.rb +34 -37
  74. data/db/migrate/20120411123334_resize_api_key_field.rb +1 -1
  75. data/lib/spree/api/engine.rb +8 -1
  76. data/lib/spree_api.rb +1 -0
  77. data/spec/controllers/spree/api/{v1/addresses_controller_spec.rb → addresses_controller_spec.rb} +3 -3
  78. data/spec/controllers/spree/api/{v1/base_controller_spec.rb → base_controller_spec.rb} +2 -9
  79. data/spec/controllers/spree/api/{v1/countries_controller_spec.rb → countries_controller_spec.rb} +5 -5
  80. data/spec/controllers/spree/api/{v1/images_controller_spec.rb → images_controller_spec.rb} +1 -1
  81. data/spec/controllers/spree/api/{v1/line_items_controller_spec.rb → line_items_controller_spec.rb} +2 -2
  82. data/spec/controllers/spree/api/{v1/orders_controller_spec.rb → orders_controller_spec.rb} +7 -12
  83. data/spec/controllers/spree/api/{v1/payments_controller_spec.rb → payments_controller_spec.rb} +2 -2
  84. data/spec/controllers/spree/api/{v1/product_properties_controller_spec.rb → product_properties_controller_spec.rb} +2 -3
  85. data/spec/controllers/spree/api/{v1/products_controller_spec.rb → products_controller_spec.rb} +14 -7
  86. data/spec/controllers/spree/api/{v1/return_authorizations_controller_spec.rb → return_authorizations_controller_spec.rb} +4 -4
  87. data/spec/controllers/spree/api/{v1/shipments_controller_spec.rb → shipments_controller_spec.rb} +4 -9
  88. data/spec/controllers/spree/api/{v1/taxonomies_controller_spec.rb → taxonomies_controller_spec.rb} +11 -11
  89. data/spec/controllers/spree/api/{v1/taxons_controller_spec.rb → taxons_controller_spec.rb} +7 -7
  90. data/spec/controllers/spree/api/{v1/unauthenticated_products_controller_spec.rb → unauthenticated_products_controller_spec.rb} +1 -1
  91. data/spec/controllers/spree/api/{v1/variants_controller_spec.rb → variants_controller_spec.rb} +4 -5
  92. data/spec/controllers/spree/api/{v1/zones_controller_spec.rb → zones_controller_spec.rb} +7 -7
  93. data/spec/support/controller_hacks.rb +1 -1
  94. data/spec/support/have_attributes_matcher.rb +2 -2
  95. data/spree_api.gemspec +1 -0
  96. metadata +139 -115
  97. checksums.yaml +0 -7
  98. data/app/controllers/spree/api/v1/addresses_controller.rb +0 -19
  99. data/app/controllers/spree/api/v1/base_controller.rb +0 -111
  100. data/app/controllers/spree/api/v1/countries_controller.rb +0 -18
  101. data/app/controllers/spree/api/v1/images_controller.rb +0 -32
  102. data/app/controllers/spree/api/v1/inventory_units_controller.rb +0 -50
  103. data/app/controllers/spree/api/v1/line_items_controller.rb +0 -40
  104. data/app/controllers/spree/api/v1/orders_controller.rb +0 -83
  105. data/app/controllers/spree/api/v1/payments_controller.rb +0 -77
  106. data/app/controllers/spree/api/v1/product_properties_controller.rb +0 -64
  107. data/app/controllers/spree/api/v1/products_controller.rb +0 -47
  108. data/app/controllers/spree/api/v1/return_authorizations_controller.rb +0 -53
  109. data/app/controllers/spree/api/v1/shipments_controller.rb +0 -43
  110. data/app/controllers/spree/api/v1/taxonomies_controller.rb +0 -50
  111. data/app/controllers/spree/api/v1/taxons_controller.rb +0 -51
  112. data/app/controllers/spree/api/v1/variants_controller.rb +0 -74
  113. data/app/controllers/spree/api/v1/zones_controller.rb +0 -45
  114. data/app/views/spree/api/v1/inventory_units/show.rabl +0 -2
  115. data/spec/controllers/spree/api/v1/inventory_units_controller_spec.rb +0 -46
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ class AddressesController < Spree::Api::BaseController
4
+ def show
5
+ @address = Address.find(params[:id])
6
+ authorize! :read, @address
7
+ end
8
+
9
+ def update
10
+ @address = Address.find(params[:id])
11
+ authorize! :read, @address
12
+ @address.update_attributes(params[:address])
13
+ render :show, :status => 200
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ module Spree
2
+ module Api
3
+ class BaseController < ActionController::Metal
4
+ include Spree::Api::ControllerSetup
5
+
6
+ attr_accessor :current_api_user
7
+
8
+ before_filter :set_content_type
9
+ before_filter :check_for_api_key, :if => :requires_authentication?
10
+ before_filter :authenticate_user
11
+ after_filter :set_jsonp_format
12
+
13
+ rescue_from CanCan::AccessDenied, :with => :unauthorized
14
+ rescue_from ActiveRecord::RecordNotFound, :with => :not_found
15
+
16
+ helper Spree::Api::ApiHelpers
17
+
18
+ def set_jsonp_format
19
+ if params[:callback] && request.get?
20
+ self.response_body = "#{params[:callback]}(#{self.response_body})"
21
+ headers["Content-Type"] = 'application/javascript'
22
+ end
23
+ end
24
+
25
+ def map_nested_attributes_keys(klass, attributes)
26
+ nested_keys = klass.nested_attributes_options.keys
27
+ attributes.inject({}) do |h, (k,v)|
28
+ key = nested_keys.include?(k.to_sym) ? "#{k}_attributes" : k
29
+ h[key] = v
30
+ h
31
+ end.with_indifferent_access
32
+ end
33
+
34
+ private
35
+
36
+ def set_content_type
37
+ content_type = case params[:format]
38
+ when "json"
39
+ "application/json"
40
+ when "xml"
41
+ "text/xml"
42
+ end
43
+ headers["Content-Type"] = content_type
44
+ end
45
+
46
+ def check_for_api_key
47
+ render "spree/api/errors/must_specify_api_key", :status => 401 and return if api_key.blank?
48
+ end
49
+
50
+ def authenticate_user
51
+ if requires_authentication? || api_key.present?
52
+ unless @current_api_user = Spree.user_class.find_by_spree_api_key(api_key)
53
+ render "spree/api/errors/invalid_api_key", :status => 401 and return
54
+ end
55
+ else
56
+ # Effectively, an anonymous user
57
+ @current_api_user = Spree.user_class.new
58
+ end
59
+ end
60
+
61
+ def unauthorized
62
+ render "spree/api/errors/unauthorized", :status => 401 and return
63
+ end
64
+
65
+ def requires_authentication?
66
+ Spree::Api::Config[:requires_authentication]
67
+ end
68
+
69
+ def not_found
70
+ render "spree/api/errors/not_found", :status => 404 and return
71
+ end
72
+
73
+ def current_ability
74
+ Spree::Ability.new(current_api_user)
75
+ end
76
+
77
+ def invalid_resource!(resource)
78
+ @resource = resource
79
+ render "spree/api/errors/invalid_resource", :status => 422
80
+ end
81
+
82
+ def api_key
83
+ request.headers["X-Spree-Token"] || params[:token]
84
+ end
85
+ helper_method :api_key
86
+
87
+ def find_product(id)
88
+ begin
89
+ product_scope.find_by_permalink!(id.to_s)
90
+ rescue ActiveRecord::RecordNotFound
91
+ product_scope.find(id)
92
+ end
93
+ end
94
+
95
+ def product_scope
96
+ if current_api_user.has_spree_role?("admin")
97
+ scope = Product
98
+ unless params[:show_deleted]
99
+ scope = scope.not_deleted
100
+ end
101
+ else
102
+ scope = Product.active
103
+ end
104
+
105
+ scope.includes(:master)
106
+ end
107
+
108
+ end
109
+ end
110
+ end
111
+
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ module Api
3
+ class CountriesController < Spree::Api::BaseController
4
+ def index
5
+ @countries = Country.ransack(params[:q]).result.includes(:states).order('name ASC')
6
+ .page(params[:page]).per(params[:per_page])
7
+ end
8
+
9
+ def show
10
+ @country = Country.find(params[:id])
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module Spree
2
+ module Api
3
+ class ImagesController < Spree::Api::BaseController
4
+ def show
5
+ @image = Image.find(params[:id])
6
+ end
7
+
8
+ def create
9
+ authorize! :create, Image
10
+ @image = Image.create(params[:image])
11
+ render :show, :status => 201
12
+ end
13
+
14
+ def update
15
+ authorize! :update, Image
16
+ @image = Image.find(params[:id])
17
+ @image.update_attributes(params[:image])
18
+ render :show, :status => 200
19
+ end
20
+
21
+ def destroy
22
+ authorize! :delete, Image
23
+ @image = Image.find(params[:id])
24
+ @image.destroy
25
+ render :text => nil, :status => 204
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ module Spree
2
+ module Api
3
+ class LineItemsController < Spree::Api::BaseController
4
+ def create
5
+ authorize! :read, order
6
+ @line_item = order.line_items.build(params[:line_item], :as => :api)
7
+ if @line_item.save
8
+ render :show, :status => 201
9
+ else
10
+ invalid_resource!(@line_item)
11
+ end
12
+ end
13
+
14
+ def update
15
+ authorize! :read, order
16
+ @line_item = order.line_items.find(params[:id])
17
+ if @line_item.update_attributes(params[:line_item])
18
+ render :show
19
+ else
20
+ invalid_resource!(@line_item)
21
+ end
22
+ end
23
+
24
+ def destroy
25
+ authorize! :read, order
26
+ @line_item = order.line_items.find(params[:id])
27
+ @line_item.destroy
28
+ render :text => nil, :status => 204
29
+ end
30
+
31
+ private
32
+
33
+ def order
34
+ @order ||= Order.find_by_number!(params[:order_id])
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,81 @@
1
+ module Spree
2
+ module Api
3
+ class OrdersController < Spree::Api::BaseController
4
+ before_filter :authorize_read!, :except => [:index, :search, :create]
5
+
6
+ def index
7
+ # should probably look at turning this into a CanCan step
8
+ raise CanCan::AccessDenied unless current_api_user.has_spree_role?("admin")
9
+ @orders = Order.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
10
+ end
11
+
12
+ def show
13
+ end
14
+
15
+ def create
16
+ @order = Order.build_from_api(current_api_user, nested_params)
17
+ next!(:status => 201)
18
+ end
19
+
20
+ def update
21
+ authorize! :update, Order
22
+ if order.update_attributes(nested_params)
23
+ order.update!
24
+ render :show
25
+ else
26
+ invalid_resource!(order)
27
+ end
28
+ end
29
+
30
+ def address
31
+ order.build_ship_address(params[:shipping_address]) if params[:shipping_address]
32
+ order.build_bill_address(params[:billing_address]) if params[:billing_address]
33
+ next!
34
+ end
35
+
36
+ def delivery
37
+ begin
38
+ ShippingMethod.find(params[:shipping_method_id])
39
+ rescue ActiveRecord::RecordNotFound
40
+ render :invalid_shipping_method, :status => 422
41
+ else
42
+ order.update_attribute(:shipping_method_id, params[:shipping_method_id])
43
+ next!
44
+ end
45
+ end
46
+
47
+ def cancel
48
+ order.cancel!
49
+ render :show
50
+ end
51
+
52
+ def empty
53
+ order.line_items.destroy_all
54
+ order.update!
55
+ render :text => nil, :status => 200
56
+ end
57
+
58
+ private
59
+
60
+ def nested_params
61
+ map_nested_attributes_keys Order, params[:order] || {}
62
+ end
63
+
64
+ def order
65
+ @order ||= Order.find_by_number!(params[:id])
66
+ end
67
+
68
+ def next!(options={})
69
+ if @order.valid? && @order.next
70
+ render :show, :status => options[:status] || 200
71
+ else
72
+ render :could_not_transition, :status => 422
73
+ end
74
+ end
75
+
76
+ def authorize_read!
77
+ authorize! :read, order
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,75 @@
1
+ module Spree
2
+ module Api
3
+ class PaymentsController < Spree::Api::BaseController
4
+ before_filter :find_order
5
+ before_filter :find_payment, :only => [:show, :authorize, :purchase, :capture, :void, :credit]
6
+
7
+ def index
8
+ @payments = @order.payments.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
9
+ end
10
+
11
+ def new
12
+ @payment_methods = Spree::PaymentMethod.where(:environment => Rails.env)
13
+ end
14
+
15
+ def create
16
+ @payment = @order.payments.build(params[:payment])
17
+ if @payment.save
18
+ render :show, :status => 201
19
+ else
20
+ invalid_resource!(@payment)
21
+ end
22
+ end
23
+
24
+ def show
25
+ end
26
+
27
+ def authorize
28
+ perform_payment_action(:authorize)
29
+ end
30
+
31
+ def capture
32
+ perform_payment_action(:capture)
33
+ end
34
+
35
+ def purchase
36
+ perform_payment_action(:purchase)
37
+ end
38
+
39
+ def void
40
+ perform_payment_action(:void_transaction)
41
+ end
42
+
43
+ def credit
44
+ if params[:amount].to_f > @payment.credit_allowed
45
+ render "spree/api/payments/credit_over_limit", :status => 422
46
+ else
47
+ perform_payment_action(:credit, params[:amount])
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def find_order
54
+ @order = Order.find_by_number(params[:order_id])
55
+ authorize! :read, @order
56
+ end
57
+
58
+ def find_payment
59
+ @payment = @order.payments.find(params[:id])
60
+ end
61
+
62
+ def perform_payment_action(action, *args)
63
+ authorize! action, Payment
64
+
65
+ begin
66
+ @payment.send("#{action}!", *args)
67
+ render :show
68
+ rescue Spree::Core::GatewayError => e
69
+ @error = e.message
70
+ render "spree/api/errors/gateway_error", :status => 422
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,61 @@
1
+ module Spree
2
+ module Api
3
+ class ProductPropertiesController < Spree::Api::BaseController
4
+ before_filter :find_product
5
+ before_filter :product_property, :only => [:show, :update, :destroy]
6
+
7
+ def index
8
+ @product_properties = @product.product_properties.ransack(params[:q]).result
9
+ .page(params[:page]).per(params[:per_page])
10
+ end
11
+
12
+ def show
13
+ end
14
+
15
+ def new
16
+ end
17
+
18
+ def create
19
+ authorize! :create, ProductProperty
20
+ @product_property = @product.product_properties.new(params[:product_property])
21
+ if @product_property.save
22
+ render :show, :status => 201
23
+ else
24
+ invalid_resource!(@product_property)
25
+ end
26
+ end
27
+
28
+ def update
29
+ authorize! :update, ProductProperty
30
+ if @product_property && @product_property.update_attributes(params[:product_property])
31
+ render :show, :status => 200
32
+ else
33
+ invalid_resource!(@product_property)
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ authorize! :delete, ProductProperty
39
+ if(@product_property)
40
+ @product_property.destroy
41
+ render :text => nil, :status => 204
42
+ else
43
+ invalid_resource!(@product_property)
44
+ end
45
+
46
+ end
47
+
48
+ private
49
+ def find_product
50
+ @product = super(params[:product_id])
51
+ end
52
+
53
+ def product_property
54
+ if @product
55
+ @product_property ||= @product.product_properties.find_by_id(params[:id])
56
+ @product_property ||= @product.product_properties.joins(:property).where('spree_properties.name' => params[:id]).readonly(false).first
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,45 @@
1
+ module Spree
2
+ module Api
3
+ class ProductsController < Spree::Api::BaseController
4
+ def index
5
+ @products = product_scope.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
6
+ end
7
+
8
+ def show
9
+ @product = find_product(params[:id])
10
+ end
11
+
12
+ def new
13
+ end
14
+
15
+ def create
16
+ authorize! :create, Product
17
+ params[:product][:available_on] ||= Time.now
18
+ @product = Product.new(params[:product])
19
+ if @product.save
20
+ render :show, :status => 201
21
+ else
22
+ invalid_resource!(@product)
23
+ end
24
+ end
25
+
26
+ def update
27
+ authorize! :update, Product
28
+ @product = find_product(params[:id])
29
+ if @product.update_attributes(params[:product])
30
+ render :show, :status => 200
31
+ else
32
+ invalid_resource!(@product)
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ authorize! :delete, Product
38
+ @product = find_product(params[:id])
39
+ @product.update_attribute(:deleted_at, Time.now)
40
+ @product.variants_including_master.update_all(:deleted_at => Time.now)
41
+ render :text => nil, :status => 204
42
+ end
43
+ end
44
+ end
45
+ end