dup_spree_api 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +22 -0
  5. data/Rakefile +30 -0
  6. data/app/controllers/spree/api/addresses_controller.rb +20 -0
  7. data/app/controllers/spree/api/base_controller.rb +114 -0
  8. data/app/controllers/spree/api/countries_controller.rb +18 -0
  9. data/app/controllers/spree/api/images_controller.rb +32 -0
  10. data/app/controllers/spree/api/line_items_controller.rb +40 -0
  11. data/app/controllers/spree/api/orders_controller.rb +85 -0
  12. data/app/controllers/spree/api/payments_controller.rb +80 -0
  13. data/app/controllers/spree/api/product_properties_controller.rb +65 -0
  14. data/app/controllers/spree/api/products_controller.rb +49 -0
  15. data/app/controllers/spree/api/return_authorizations_controller.rb +54 -0
  16. data/app/controllers/spree/api/shipments_controller.rb +43 -0
  17. data/app/controllers/spree/api/taxonomies_controller.rb +50 -0
  18. data/app/controllers/spree/api/taxons_controller.rb +53 -0
  19. data/app/controllers/spree/api/variants_controller.rb +75 -0
  20. data/app/controllers/spree/api/zones_controller.rb +46 -0
  21. data/app/helpers/spree/api/api_helpers.rb +76 -0
  22. data/app/models/spree/api_configuration.rb +5 -0
  23. data/app/models/spree/line_item_decorator.rb +3 -0
  24. data/app/models/spree/option_value_decorator.rb +5 -0
  25. data/app/models/spree/order_decorator.rb +13 -0
  26. data/app/models/spree/user_decorator.rb +13 -0
  27. data/app/overrides/api_admin_user_edit_form.rb +6 -0
  28. data/app/views/spree/admin/users/_api_fields.html.erb +32 -0
  29. data/app/views/spree/api/addresses/show.v1.rabl +11 -0
  30. data/app/views/spree/api/countries/index.v1.rabl +7 -0
  31. data/app/views/spree/api/countries/show.v1.rabl +5 -0
  32. data/app/views/spree/api/errors/gateway_error.v1.rabl +2 -0
  33. data/app/views/spree/api/errors/invalid_api_key.v1.rabl +2 -0
  34. data/app/views/spree/api/errors/invalid_resource.v1.rabl +3 -0
  35. data/app/views/spree/api/errors/must_specify_api_key.v1.rabl +2 -0
  36. data/app/views/spree/api/errors/not_found.v1.rabl +2 -0
  37. data/app/views/spree/api/errors/unauthorized.v1.rabl +2 -0
  38. data/app/views/spree/api/images/show.v1.rabl +3 -0
  39. data/app/views/spree/api/line_items/new.v1.rabl +3 -0
  40. data/app/views/spree/api/line_items/show.v1.rabl +5 -0
  41. data/app/views/spree/api/orders/address.v1.rabl +0 -0
  42. data/app/views/spree/api/orders/canceled.v1.rabl +0 -0
  43. data/app/views/spree/api/orders/cart.v1.rabl +0 -0
  44. data/app/views/spree/api/orders/complete.v1.rabl +0 -0
  45. data/app/views/spree/api/orders/could_not_transition.v1.rabl +3 -0
  46. data/app/views/spree/api/orders/delivery.v1.rabl +3 -0
  47. data/app/views/spree/api/orders/index.v1.rabl +7 -0
  48. data/app/views/spree/api/orders/invalid_shipping_method.v1.rabl +2 -0
  49. data/app/views/spree/api/orders/payment.v1.rabl +4 -0
  50. data/app/views/spree/api/orders/show.v1.rabl +29 -0
  51. data/app/views/spree/api/payments/credit_over_limit.v1.rabl +2 -0
  52. data/app/views/spree/api/payments/index.v1.rabl +7 -0
  53. data/app/views/spree/api/payments/new.v1.rabl +6 -0
  54. data/app/views/spree/api/payments/show.v1.rabl +2 -0
  55. data/app/views/spree/api/product_properties/index.v1.rabl +7 -0
  56. data/app/views/spree/api/product_properties/new.v1.rabl +2 -0
  57. data/app/views/spree/api/product_properties/show.v1.rabl +2 -0
  58. data/app/views/spree/api/products/index.v1.rabl +8 -0
  59. data/app/views/spree/api/products/new.v1.rabl +3 -0
  60. data/app/views/spree/api/products/product.v1.rabl +1 -0
  61. data/app/views/spree/api/products/show.v1.rabl +25 -0
  62. data/app/views/spree/api/return_authorizations/index.v1.rabl +7 -0
  63. data/app/views/spree/api/return_authorizations/new.v1.rabl +3 -0
  64. data/app/views/spree/api/return_authorizations/show.v1.rabl +2 -0
  65. data/app/views/spree/api/shipments/cannot_ready_shipment.v1.rabl +2 -0
  66. data/app/views/spree/api/shipments/show.v1.rabl +7 -0
  67. data/app/views/spree/api/taxonomies/index.v1.rabl +7 -0
  68. data/app/views/spree/api/taxonomies/nested.v1.rabl +11 -0
  69. data/app/views/spree/api/taxonomies/new.v1.rabl +3 -0
  70. data/app/views/spree/api/taxonomies/show.v1.rabl +15 -0
  71. data/app/views/spree/api/taxons/index.v1.rabl +4 -0
  72. data/app/views/spree/api/taxons/new.v1.rabl +3 -0
  73. data/app/views/spree/api/taxons/show.v1.rabl +8 -0
  74. data/app/views/spree/api/taxons/taxons.v1.rabl +7 -0
  75. data/app/views/spree/api/variants/index.v1.rabl +10 -0
  76. data/app/views/spree/api/variants/new.v1.rabl +2 -0
  77. data/app/views/spree/api/variants/show.v1.rabl +3 -0
  78. data/app/views/spree/api/variants/variant.v1.rabl +1 -0
  79. data/app/views/spree/api/zones/index.v1.rabl +7 -0
  80. data/app/views/spree/api/zones/show.v1.rabl +6 -0
  81. data/config/initializers/metal_load_paths.rb +1 -0
  82. data/config/locales/en.yml +23 -0
  83. data/config/routes.rb +56 -0
  84. data/db/migrate/20100107141738_add_api_key_to_spree_users.rb +7 -0
  85. data/db/migrate/20120411123334_resize_api_key_field.rb +7 -0
  86. data/db/migrate/20120530054546_rename_api_key_to_spree_api_key.rb +7 -0
  87. data/lib/spree/api.rb +12 -0
  88. data/lib/spree/api/controller_setup.rb +27 -0
  89. data/lib/spree/api/engine.rb +35 -0
  90. data/lib/spree/api/responders.rb +11 -0
  91. data/lib/spree/api/responders/rabl_template.rb +22 -0
  92. data/lib/spree/api/testing_support/helpers.rb +35 -0
  93. data/lib/spree/api/testing_support/setup.rb +28 -0
  94. data/lib/spree/api/version.rb +5 -0
  95. data/lib/spree_api.rb +3 -0
  96. data/script/rails +9 -0
  97. data/spec/controllers/spree/api/addresses_controller_spec.rb +45 -0
  98. data/spec/controllers/spree/api/base_controller_spec.rb +42 -0
  99. data/spec/controllers/spree/api/countries_controller_spec.rb +48 -0
  100. data/spec/controllers/spree/api/images_controller_spec.rb +66 -0
  101. data/spec/controllers/spree/api/line_items_controller_spec.rb +77 -0
  102. data/spec/controllers/spree/api/orders_controller_spec.rb +255 -0
  103. data/spec/controllers/spree/api/payments_controller_spec.rb +203 -0
  104. data/spec/controllers/spree/api/product_properties_controller_spec.rb +116 -0
  105. data/spec/controllers/spree/api/products_controller_spec.rb +211 -0
  106. data/spec/controllers/spree/api/return_authorizations_controller_spec.rb +155 -0
  107. data/spec/controllers/spree/api/shipments_controller_spec.rb +59 -0
  108. data/spec/controllers/spree/api/taxonomies_controller_spec.rb +107 -0
  109. data/spec/controllers/spree/api/taxons_controller_spec.rb +87 -0
  110. data/spec/controllers/spree/api/unauthenticated_products_controller_spec.rb +26 -0
  111. data/spec/controllers/spree/api/variants_controller_spec.rb +155 -0
  112. data/spec/controllers/spree/api/zones_controller_spec.rb +111 -0
  113. data/spec/fixtures/thinking-cat.jpg +0 -0
  114. data/spec/models/spree/legacy_user_spec.rb +19 -0
  115. data/spec/models/spree/order_spec.rb +18 -0
  116. data/spec/shared_examples/protect_product_actions.rb +17 -0
  117. data/spec/spec_helper.rb +27 -0
  118. data/spec/support/controller_hacks.rb +27 -0
  119. data/spec/support/database_cleaner.rb +14 -0
  120. data/spec/support/have_attributes_matcher.rb +13 -0
  121. data/spree_api.gemspec +23 -0
  122. metadata +254 -0
@@ -0,0 +1,65 @@
1
+ module Spree
2
+ module Api
3
+ class ProductPropertiesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ before_filter :find_product
7
+ before_filter :product_property, :only => [:show, :update, :destroy]
8
+
9
+ def index
10
+ @product_properties = @product.product_properties.ransack(params[:q]).result
11
+ .page(params[:page]).per(params[:per_page])
12
+ respond_with(@product_properties)
13
+ end
14
+
15
+ def show
16
+ respond_with(@product_property)
17
+ end
18
+
19
+ def new
20
+ end
21
+
22
+ def create
23
+ authorize! :create, ProductProperty
24
+ @product_property = @product.product_properties.new(params[:product_property])
25
+ if @product_property.save
26
+ respond_with(@product_property, :status => 201, :default_template => :show)
27
+ else
28
+ invalid_resource!(@product_property)
29
+ end
30
+ end
31
+
32
+ def update
33
+ authorize! :update, ProductProperty
34
+ if @product_property && @product_property.update_attributes(params[:product_property])
35
+ respond_with(@product_property, :status => 200, :default_template => :show)
36
+ else
37
+ invalid_resource!(@product_property)
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ authorize! :delete, ProductProperty
43
+ if(@product_property)
44
+ @product_property.destroy
45
+ respond_with(@product_property, :status => 204)
46
+ else
47
+ invalid_resource!(@product_property)
48
+ end
49
+
50
+ end
51
+
52
+ private
53
+ def find_product
54
+ @product = super(params[:product_id])
55
+ end
56
+
57
+ def product_property
58
+ if @product
59
+ @product_property ||= @product.product_properties.find_by_id(params[:id])
60
+ @product_property ||= @product.product_properties.joins(:property).where('spree_properties.name' => params[:id]).readonly(false).first
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ module Spree
2
+ module Api
3
+ class ProductsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ def index
7
+ @products = product_scope.ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
8
+ respond_with(@products)
9
+ end
10
+
11
+ def show
12
+ @product = find_product(params[:id])
13
+ respond_with(@product)
14
+ end
15
+
16
+ def new
17
+ end
18
+
19
+ def create
20
+ authorize! :create, Product
21
+ params[:product][:available_on] ||= Time.now
22
+ @product = Product.new(params[:product])
23
+ if @product.save
24
+ respond_with(@product, :status => 201, :default_template => :show)
25
+ else
26
+ invalid_resource!(@product)
27
+ end
28
+ end
29
+
30
+ def update
31
+ authorize! :update, Product
32
+ @product = find_product(params[:id])
33
+ if @product.update_attributes(params[:product])
34
+ respond_with(@product, :status => 200, :default_template => :show)
35
+ else
36
+ invalid_resource!(@product)
37
+ end
38
+ end
39
+
40
+ def destroy
41
+ authorize! :delete, Product
42
+ @product = find_product(params[:id])
43
+ @product.update_attribute(:deleted_at, Time.now)
44
+ @product.variants_including_master.update_all(:deleted_at => Time.now)
45
+ respond_with(@product, :status => 204)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,54 @@
1
+ module Spree
2
+ module Api
3
+ class ReturnAuthorizationsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ before_filter :authorize_admin!
7
+
8
+ def index
9
+ @return_authorizations = order.return_authorizations.ransack(params[:q]).result
10
+ .page(params[:page]).per(params[:per_page])
11
+ respond_with(@return_authorizations)
12
+ end
13
+
14
+ def show
15
+ @return_authorization = order.return_authorizations.find(params[:id])
16
+ respond_with(@return_authorization)
17
+ end
18
+
19
+ def create
20
+ @return_authorization = order.return_authorizations.build(params[:return_authorization], :as => :api)
21
+ if @return_authorization.save
22
+ respond_with(@return_authorization, :status => 201, :default_template => :show)
23
+ else
24
+ invalid_resource!(@return_authorization)
25
+ end
26
+ end
27
+
28
+ def update
29
+ @return_authorization = order.return_authorizations.find(params[:id])
30
+ if @return_authorization.update_attributes(params[:return_authorization])
31
+ respond_with(@return_authorization, :default_template => :show)
32
+ else
33
+ invalid_resource!(@return_authorization)
34
+ end
35
+ end
36
+
37
+ def destroy
38
+ @return_authorization = order.return_authorizations.find(params[:id])
39
+ @return_authorization.destroy
40
+ respond_with(@return_authorization, :status => 204)
41
+ end
42
+
43
+ private
44
+
45
+ def order
46
+ @order ||= Order.find_by_number!(params[:order_id])
47
+ end
48
+
49
+ def authorize_admin!
50
+ authorize! :manage, Spree::ReturnAuthorization
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,43 @@
1
+ module Spree
2
+ module Api
3
+ class ShipmentsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ before_filter :find_order
7
+ before_filter :find_and_update_shipment, :only => [:ship, :ready]
8
+
9
+ def ready
10
+ authorize! :read, Shipment
11
+ unless @shipment.ready?
12
+ if @shipment.can_ready?
13
+ @shipment.ready!
14
+ else
15
+ render "spree/api/shipments/cannot_ready_shipment", :status => 422 and return
16
+ end
17
+ end
18
+ respond_with(@shipment, :default_template => :show)
19
+ end
20
+
21
+ def ship
22
+ authorize! :read, Shipment
23
+ unless @shipment.shipped?
24
+ @shipment.ship!
25
+ end
26
+ respond_with(@shipment, :default_template => :show)
27
+ end
28
+
29
+ private
30
+
31
+ def find_order
32
+ @order = Spree::Order.find_by_number!(params[:order_id])
33
+ authorize! :read, @order
34
+ end
35
+
36
+ def find_and_update_shipment
37
+ @shipment = @order.shipments.find_by_number!(params[:id])
38
+ @shipment.update_attributes(params[:shipment])
39
+ @shipment.reload
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,50 @@
1
+ module Spree
2
+ module Api
3
+ class TaxonomiesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ def index
7
+ @taxonomies = Taxonomy.order('name').includes(:root => :children).ransack(params[:q]).result
8
+ .page(params[:page]).per(params[:per_page])
9
+ respond_with(@taxonomies)
10
+ end
11
+
12
+ def show
13
+ @taxonomy = Taxonomy.find(params[:id])
14
+ respond_with(@taxonomy)
15
+ end
16
+
17
+ def create
18
+ authorize! :create, Taxonomy
19
+ @taxonomy = Taxonomy.new(params[:taxonomy])
20
+ if @taxonomy.save
21
+ respond_with(@taxonomy, :status => 201, :default_template => :show)
22
+ else
23
+ invalid_resource!(@taxonomy)
24
+ end
25
+ end
26
+
27
+ def update
28
+ authorize! :update, Taxonomy
29
+ if taxonomy.update_attributes(params[:taxonomy])
30
+ respond_with(taxonomy, :status => 200, :default_template => :show)
31
+ else
32
+ invalid_resource!(taxonomy)
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ authorize! :delete, Taxonomy
38
+ taxonomy.destroy
39
+ respond_with(taxonomy, :status => 204)
40
+ end
41
+
42
+ private
43
+
44
+ def taxonomy
45
+ @taxonomy ||= Taxonomy.find(params[:id])
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ module Spree
2
+ module Api
3
+ class TaxonsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ def index
7
+ @taxons = taxonomy.root.children
8
+ respond_with(@taxons)
9
+ end
10
+
11
+ def show
12
+ @taxon = taxon
13
+ respond_with(@taxon)
14
+ end
15
+
16
+ def create
17
+ authorize! :create, Taxon
18
+ @taxon = Taxon.new(params[:taxon])
19
+ if @taxon.save
20
+ respond_with(@taxon, :status => 201, :default_template => :show)
21
+ else
22
+ invalid_resource!(@taxon)
23
+ end
24
+ end
25
+
26
+ def update
27
+ authorize! :update, Taxon
28
+ if taxon.update_attributes(params[:taxon])
29
+ respond_with(taxon, :status => 200, :default_template => :show)
30
+ else
31
+ invalid_resource!(taxon)
32
+ end
33
+ end
34
+
35
+ def destroy
36
+ authorize! :delete, Taxon
37
+ taxon.destroy
38
+ respond_with(taxon, :status => 204)
39
+ end
40
+
41
+ private
42
+
43
+ def taxonomy
44
+ @taxonomy ||= Taxonomy.find(params[:taxonomy_id])
45
+ end
46
+
47
+ def taxon
48
+ @taxon ||= taxonomy.taxons.find(params[:id])
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,75 @@
1
+ module Spree
2
+ module Api
3
+ class VariantsController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ before_filter :product
7
+
8
+ def index
9
+ @variants = scope.includes(:option_values).ransack(params[:q]).result.
10
+ page(params[:page]).per(params[:per_page])
11
+ respond_with(@variants)
12
+ end
13
+
14
+ def show
15
+ @variant = scope.includes(:option_values).find(params[:id])
16
+ respond_with(@variant)
17
+ end
18
+
19
+ def new
20
+ end
21
+
22
+ def create
23
+ authorize! :create, Variant
24
+ @variant = scope.new(params[:product])
25
+ if @variant.save
26
+ respond_with(@variant, :status => 201, :default_template => :show)
27
+ else
28
+ invalid_resource!(@variant)
29
+ end
30
+ end
31
+
32
+ def update
33
+ authorize! :update, Variant
34
+ @variant = scope.find(params[:id])
35
+ if @variant.update_attributes(params[:variant])
36
+ respond_with(@variant, :status => 200, :default_template => :show)
37
+ else
38
+ invalid_resource!(@product)
39
+ end
40
+ end
41
+
42
+ def destroy
43
+ authorize! :delete, Variant
44
+ @variant = scope.find(params[:id])
45
+ @variant.destroy
46
+ respond_with(@variant, :status => 204)
47
+ end
48
+
49
+ private
50
+ def product
51
+ @product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id]
52
+ end
53
+
54
+ def scope
55
+ if @product
56
+ unless current_api_user.has_spree_role?("admin") || params[:show_deleted]
57
+ variants = @product.variants_including_master
58
+ else
59
+ variants = @product.variants_including_master_and_deleted
60
+ end
61
+ else
62
+ variants = Variant.scoped
63
+ if current_api_user.has_spree_role?("admin")
64
+ unless params[:show_deleted]
65
+ variants = Variant.active
66
+ end
67
+ else
68
+ variants = variants.active
69
+ end
70
+ end
71
+ variants
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,46 @@
1
+ module Spree
2
+ module Api
3
+ class ZonesController < Spree::Api::BaseController
4
+ respond_to :json
5
+
6
+ def index
7
+ @zones = Zone.order('name ASC').ransack(params[:q]).result.page(params[:page]).per(params[:per_page])
8
+ respond_with(@zones)
9
+ end
10
+
11
+ def show
12
+ respond_with(zone)
13
+ end
14
+
15
+ def create
16
+ authorize! :create, Zone
17
+ @zone = Zone.new(map_nested_attributes_keys(Spree::Zone, params[:zone]))
18
+ if @zone.save
19
+ respond_with(@zone, :status => 201, :default_template => :show)
20
+ else
21
+ invalid_resource!(@zone)
22
+ end
23
+ end
24
+
25
+ def update
26
+ authorize! :update, Zone
27
+ if zone.update_attributes(map_nested_attributes_keys(Spree::Zone, params[:zone]))
28
+ respond_with(zone, :status => 200, :default_template => :show)
29
+ else
30
+ invalid_resource!(zone)
31
+ end
32
+ end
33
+
34
+ def destroy
35
+ authorize! :delete, Zone
36
+ zone.destroy
37
+ respond_with(zone, :status => 204)
38
+ end
39
+
40
+ private
41
+ def zone
42
+ @zone ||= Spree::Zone.find(params[:id])
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,76 @@
1
+ module Spree
2
+ module Api
3
+ module ApiHelpers
4
+ def required_fields_for(model)
5
+ required_fields = model._validators.select do |field, validations|
6
+ validations.any? { |v| v.is_a?(ActiveModel::Validations::PresenceValidator) }
7
+ end.map(&:first) # get fields that are invalid
8
+ # Permalinks presence is validated, but are really automatically generated
9
+ # Therefore we shouldn't tell API clients that they MUST send one through
10
+ required_fields.map!(&:to_s).delete("permalink")
11
+ required_fields
12
+ end
13
+
14
+ def product_attributes
15
+ [:id, :name, :description, :price, :available_on, :permalink,
16
+ :count_on_hand, :meta_description, :meta_keywords, :taxon_ids]
17
+ end
18
+
19
+ def product_property_attributes
20
+ [:id, :product_id, :property_id, :value, :property_name]
21
+ end
22
+
23
+ def variant_attributes
24
+ [:id, :name, :count_on_hand, :sku, :price, :weight, :height, :width, :depth, :is_master, :cost_price, :permalink]
25
+ end
26
+
27
+ def image_attributes
28
+ [:id, :position, :attachment_content_type, :attachment_file_name, :type, :attachment_updated_at, :attachment_width, :attachment_height, :alt]
29
+ end
30
+
31
+ def option_value_attributes
32
+ [:id, :name, :presentation, :option_type_name, :option_type_id]
33
+ end
34
+
35
+ def order_attributes
36
+ [:id, :number, :item_total, :total, :state, :adjustment_total, :user_id, :created_at, :updated_at, :completed_at, :payment_total, :shipment_state, :payment_state, :email, :special_instructions]
37
+ end
38
+
39
+ def line_item_attributes
40
+ [:id, :quantity, :price, :variant_id]
41
+ end
42
+
43
+ def option_type_attributes
44
+ [:id, :name, :presentation, :position]
45
+ end
46
+
47
+ def payment_attributes
48
+ [:id, :source_type, :source_id, :amount, :payment_method_id, :response_code, :state, :avs_response, :created_at, :updated_at]
49
+ end
50
+
51
+ def payment_method_attributes
52
+ [:id, :name, :description]
53
+ end
54
+
55
+ def shipment_attributes
56
+ [:id, :tracking, :number, :cost, :shipped_at, :state]
57
+ end
58
+
59
+ def taxonomy_attributes
60
+ [:id, :name]
61
+ end
62
+
63
+ def taxon_attributes
64
+ [:id, :name, :permalink, :position, :parent_id, :taxonomy_id]
65
+ end
66
+
67
+ def return_authorization_attributes
68
+ [:id, :number, :state, :amount, :order_id, :reason, :created_at, :updated_at]
69
+ end
70
+
71
+ def country_attributes
72
+ [:id, :iso_name, :iso, :iso3, :name, :numcode]
73
+ end
74
+ end
75
+ end
76
+ end