spree 0.6.0 → 0.7.0

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.
Files changed (181) hide show
  1. data/CHANGELOG +30 -0
  2. data/CONTRIBUTORS +38 -20
  3. data/app/controllers/admin/creditcard_payments_controller.rb +10 -3
  4. data/app/controllers/admin/orders_controller.rb +17 -16
  5. data/app/controllers/admin/products_controller.rb +12 -14
  6. data/app/controllers/admin/reports_controller.rb +12 -14
  7. data/app/controllers/admin/users_controller.rb +10 -5
  8. data/app/controllers/admin/zones_controller.rb +4 -1
  9. data/app/controllers/application.rb +0 -1
  10. data/app/controllers/checkout_controller.rb +96 -0
  11. data/app/controllers/content_controller.rb +11 -1
  12. data/app/controllers/orders_controller.rb +12 -33
  13. data/app/controllers/products_controller.rb +12 -7
  14. data/app/controllers/spree/base_controller.rb +1 -1
  15. data/app/controllers/states_controller.rb +14 -2
  16. data/app/controllers/taxons_controller.rb +6 -2
  17. data/app/controllers/users_controller.rb +9 -6
  18. data/app/helpers/application_helper.rb +1 -11
  19. data/app/helpers/products_helper.rb +3 -1
  20. data/app/helpers/spree/base_helper.rb +0 -26
  21. data/app/models/address.rb +3 -3
  22. data/app/models/app_configuration.rb +1 -0
  23. data/app/models/country.rb +4 -0
  24. data/app/models/creditcard.rb +6 -1
  25. data/app/models/creditcard_payment.rb +1 -1
  26. data/app/models/inventory_unit.rb +4 -1
  27. data/app/models/order.rb +37 -21
  28. data/app/models/product.rb +19 -8
  29. data/{vendor/extensions/shipping/app → app}/models/shipment.rb +20 -4
  30. data/{vendor/extensions/shipping/app → app}/models/shipping_category.rb +0 -0
  31. data/{vendor/extensions/shipping/app → app}/models/shipping_method.rb +6 -4
  32. data/app/models/state.rb +5 -0
  33. data/app/models/user.rb +4 -2
  34. data/app/models/variant.rb +19 -1
  35. data/app/presenters/checkout_presenter.rb +58 -0
  36. data/app/views/admin/creditcard_payments/edit.html.erb +1 -1
  37. data/app/views/admin/option_types/available.html.erb +1 -1
  38. data/app/views/admin/orders/index.html.erb +28 -18
  39. data/app/views/admin/orders/show.html.erb +1 -1
  40. data/app/views/admin/payments/index.html.erb +1 -1
  41. data/app/views/admin/products/_images.html.erb +1 -1
  42. data/app/views/admin/products/index.html.erb +17 -13
  43. data/app/views/admin/users/index.html.erb +8 -8
  44. data/app/views/admin/zones/index.html.erb +5 -2
  45. data/app/views/checkout/_form.html.erb +165 -0
  46. data/app/views/{creditcards → checkout}/cvv.html.erb +1 -1
  47. data/app/views/checkout/new.html.erb +6 -0
  48. data/app/views/layouts/admin.html.erb +2 -3
  49. data/app/views/layouts/application.html.erb +1 -1
  50. data/app/views/orders/_form.html.erb +6 -4
  51. data/app/views/orders/_google_order.html.erb +24 -0
  52. data/app/views/orders/_line_item.html.erb +2 -1
  53. data/app/views/orders/show.html.erb +4 -1
  54. data/app/views/products/index.html.erb +2 -1
  55. data/app/views/products/show.html.erb +4 -4
  56. data/app/views/shared/_footer.html.erb +12 -1
  57. data/app/views/shared/_login.html.erb +1 -1
  58. data/app/views/shared/_order_details.html.erb +8 -9
  59. data/app/views/shared/_products.html.erb +1 -1
  60. data/app/views/shared/_report_criteria.html.erb +28 -28
  61. data/app/views/states/index.js.erb +10 -1
  62. data/config/environment.rb +10 -4
  63. data/config/initializers/searchlogic.rb +6 -0
  64. data/config/locales/de.yml +14 -0
  65. data/config/locales/en-GB.yml +20 -6
  66. data/config/locales/en-US.yml +20 -4
  67. data/config/locales/es.yml +14 -0
  68. data/config/locales/fr-FR.yml +463 -0
  69. data/config/locales/fr-FR_rails.yml +115 -0
  70. data/config/locales/it.yml +14 -0
  71. data/config/locales/nb-NO.yml +457 -0
  72. data/config/locales/nb-NO_rails.yml +105 -0
  73. data/config/locales/pl.yml +14 -0
  74. data/config/locales/pt-BR.yml +14 -0
  75. data/config/locales/pt-PT.yml +14 -0
  76. data/config/locales/ru-RU.yml +458 -0
  77. data/config/locales/ru-RU_rails.yml +154 -0
  78. data/config/routes.rb +11 -4
  79. data/db/migrate/20090204200045_add_order_permalink.rb +13 -0
  80. data/db/migrate/20090225231119_add_more_needed_keys_items_and_conf.rb +19 -0
  81. data/db/migrate/20090302221152_give_all_users_user_role.rb +13 -0
  82. data/db/sample/orders.yml +1 -1
  83. data/lib/generators/instance/instance_generator.rb +1 -1
  84. data/lib/spree.rb +1 -1
  85. data/lib/spree/setup.rb +1 -1
  86. data/lib/tasks/database.rake +5 -2
  87. data/lib/tasks/release.rake +1 -1
  88. data/lib/tasks/upgrade.rake +11 -0
  89. data/public/assets/products/1009/mini/sean.jpg +0 -0
  90. data/public/assets/products/1009/original/sean.jpg +0 -0
  91. data/public/assets/products/1009/product/sean.jpg +0 -0
  92. data/public/assets/products/1009/small/sean.jpg +0 -0
  93. data/public/images/ajax_loader.gif +0 -0
  94. data/public/javascripts/checkout.js +284 -0
  95. data/public/javascripts/jquery-1.3.2.min.js +19 -0
  96. data/public/javascripts/jquery.validate.pack.js +15 -0
  97. data/public/stylesheets/checkout.css +25 -0
  98. data/public/stylesheets/spree-admin.css +6 -2
  99. data/public/stylesheets/spree.css +419 -432
  100. data/spec/controllers/countries_controller_spec.rb +3 -2
  101. data/spec/controllers/orders_controller_spec.rb +7 -5
  102. data/spec/controllers/states_controller_spec.rb +4 -2
  103. data/spec/models/creditcard_payment_spec.rb +6 -2
  104. data/spec/models/order_spec.rb +164 -157
  105. data/spec/models/product_spec.rb +2 -2
  106. data/vendor/extensions/payment_gateway/db/migrate/20090218091936_create_protx_gateway.rb +18 -0
  107. data/vendor/extensions/payment_gateway/lib/spree/payment_gateway.rb +7 -5
  108. data/vendor/extensions/shipping/app/controllers/admin/shipments_controller.rb +6 -5
  109. data/vendor/extensions/shipping/app/views/admin/shipments/index.html.erb +1 -1
  110. data/vendor/extensions/shipping/config/locales/nb-NO.yml +25 -0
  111. data/vendor/extensions/shipping/config/locales/ru-RU.yml +25 -0
  112. data/vendor/extensions/shipping/db/sample/shipping_methods.yml +5 -1
  113. data/vendor/extensions/shipping/db/sample/zone_members.yml +9 -1
  114. data/vendor/extensions/shipping/db/sample/zones.yml +4 -1
  115. data/vendor/extensions/shipping/lib/spree/shipping_calculator.rb +0 -16
  116. data/vendor/extensions/shipping/shipping_extension.rb +0 -15
  117. data/vendor/extensions/shipping/spec/models/shipping_method_spec.rb +16 -10
  118. data/vendor/extensions/shipping/spec/models/shipping_order_spec.rb +3 -17
  119. data/vendor/extensions/tax_calculator/config/locales/nb-NO.yml +30 -0
  120. data/vendor/extensions/tax_calculator/spec/models/{order_spec.rb → order_tax_calc_spec.rb} +2 -2
  121. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/.specification +3 -5
  122. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/LICENSE +0 -0
  123. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/README +9 -2
  124. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/Rakefile +0 -0
  125. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter.rb +0 -0
  126. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/base.rb +38 -8
  127. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/version.rb +1 -1
  128. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/doc.rake +0 -0
  129. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/gem.rake +0 -0
  130. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/base_test.rb +66 -30
  131. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/test_helper.rb +36 -0
  132. data/vendor/plugins/attribute_fu/lib/attribute_fu/associated_form_helper.rb +12 -4
  133. data/vendor/plugins/find_by_param/MIT-LICENSE +1 -1
  134. data/vendor/plugins/find_by_param/{README → README.markdown} +7 -1
  135. data/vendor/plugins/find_by_param/init.rb +0 -1
  136. data/vendor/plugins/find_by_param/lib/find_by_param.rb +23 -87
  137. data/vendor/plugins/find_by_param/test/find_by_param_test.rb +22 -8
  138. data/vendor/plugins/find_by_param/test/test_helper.rb +0 -1
  139. metadata +65 -193
  140. data/app/controllers/creditcards_controller.rb +0 -73
  141. data/app/models/order_filter.rb +0 -28
  142. data/app/models/user_filter.rb +0 -6
  143. data/app/views/creditcards/_form_credit_card.html.erb +0 -30
  144. data/app/views/creditcards/new.html.erb +0 -25
  145. data/app/views/shared/_paginate.html.erb +0 -34
  146. data/lib/plugins/paginating_find/CHANGELOG +0 -120
  147. data/lib/plugins/paginating_find/README +0 -89
  148. data/lib/plugins/paginating_find/init.rb +0 -2
  149. data/lib/plugins/paginating_find/lib/paginating_find.rb +0 -138
  150. data/lib/plugins/paginating_find/lib/paging_enumerator.rb +0 -158
  151. data/lib/plugins/paginating_find/lib/paging_helper.rb +0 -47
  152. data/lib/plugins/paginating_find/test_app/Rakefile +0 -10
  153. data/lib/plugins/paginating_find/test_app/app/controllers/application.rb +0 -2
  154. data/lib/plugins/paginating_find/test_app/config/boot.rb +0 -44
  155. data/lib/plugins/paginating_find/test_app/config/database.yml +0 -6
  156. data/lib/plugins/paginating_find/test_app/config/environment.rb +0 -53
  157. data/lib/plugins/paginating_find/test_app/config/environments/test.rb +0 -19
  158. data/lib/plugins/paginating_find/test_app/config/routes.rb +0 -22
  159. data/lib/plugins/paginating_find/test_app/script/breakpointer +0 -3
  160. data/lib/plugins/paginating_find/test_app/script/console +0 -3
  161. data/lib/plugins/paginating_find/test_app/test/fixtures/articles.yml +0 -19
  162. data/lib/plugins/paginating_find/test_app/test/fixtures/authors.yml +0 -7
  163. data/lib/plugins/paginating_find/test_app/test/fixtures/edits.yml +0 -11
  164. data/lib/plugins/paginating_find/test_app/test/fixtures/models.rb +0 -18
  165. data/lib/plugins/paginating_find/test_app/test/test_helper.rb +0 -33
  166. data/lib/plugins/paginating_find/test_app/test/unit/abstract_test.rb +0 -7
  167. data/lib/plugins/paginating_find/test_app/test/unit/group_test.rb +0 -40
  168. data/lib/plugins/paginating_find/test_app/test/unit/paginating_find_test.rb +0 -194
  169. data/lib/plugins/paginating_find/test_app/test/unit/paging_enumerator_test.rb +0 -143
  170. data/public/assets/products/1012/mini/bt.jpg +0 -0
  171. data/public/assets/products/1012/original/bt.jpg +0 -0
  172. data/public/assets/products/1012/product/bt.jpg +0 -0
  173. data/public/assets/products/1012/small/bt.jpg +0 -0
  174. data/spec/views/products/index.html.erb_spec.rb +0 -46
  175. data/spec/views/products/show.html.erb_spec.rb +0 -46
  176. data/vendor/extensions/shipping/app/controllers/shipments_controller.rb +0 -96
  177. data/vendor/extensions/shipping/app/helpers/shipments_helper.rb +0 -20
  178. data/vendor/extensions/shipping/app/views/orders/fatal_shipping.html.erb +0 -6
  179. data/vendor/extensions/shipping/app/views/shipments/_form.html.erb +0 -46
  180. data/vendor/extensions/shipping/app/views/shipments/edit.html.erb +0 -57
  181. data/vendor/extensions/shipping/app/views/shipments/new.html.erb +0 -10
@@ -2,7 +2,7 @@ module ActivePresenter
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 4
5
+ TINY = 6
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,79 +1,87 @@
1
1
  require File.dirname(__FILE__)+'/test_helper'
2
2
 
3
3
  Expectations do
4
+ expect nil do
5
+ SignupPresenter.new.id
6
+ end
7
+
8
+ expect true do
9
+ SignupPresenter.new.new_record?
10
+ end
11
+
4
12
  expect :user => User, :account => Account do
5
13
  SignupPresenter.presented
6
14
  end
7
-
15
+
8
16
  expect User.create!(hash_for_user) do |u|
9
17
  SignupPresenter.new(:user => u.expected).user
10
18
  end
11
-
19
+
12
20
  expect User do
13
21
  SignupPresenter.new.user
14
22
  end
15
-
23
+
16
24
  expect User.any_instance.to.receive(:login=).with('james') do
17
25
  SignupPresenter.new(:user_login => 'james')
18
26
  end
19
-
27
+
20
28
  # admin= should be protected from mass assignment
21
29
  expect SignupPresenter.new.to.be.attribute_protected?(:user_admin)
22
30
  expect SignupPresenter.new(:user_admin => true).user.not.to.be.admin?
23
-
31
+
24
32
  expect 'mymockvalue' do
25
33
  User.any_instance.stubs(:login).returns('mymockvalue')
26
34
  SignupPresenter.new.user_login
27
35
  end
28
-
36
+
29
37
  expect User.any_instance.to.receive(:login=).with('mymockvalue') do
30
38
  SignupPresenter.new.user_login = 'mymockvalue'
31
39
  end
32
-
40
+
33
41
  expect SignupPresenter.new.not.to.be.valid?
34
42
  expect SignupPresenter.new(:user => User.new(hash_for_user)).to.be.valid?
35
-
43
+
36
44
  expect ActiveRecord::Errors do
37
45
  s = SignupPresenter.new
38
46
  s.valid?
39
47
  s.errors
40
48
  end
41
-
49
+
42
50
  expect ActiveRecord::Errors do
43
51
  s = SignupPresenter.new
44
52
  s.valid?
45
53
  s.user_errors
46
54
  end
47
-
55
+
48
56
  expect ActiveRecord::Errors do
49
57
  s = SignupPresenter.new
50
58
  s.valid?
51
59
  s.account_errors
52
60
  end
53
-
61
+
54
62
  expect String do
55
63
  s = SignupPresenter.new
56
64
  s.valid?
57
65
  s.errors.on(:user_login)
58
66
  end
59
-
67
+
60
68
  expect ActiveRecord::Base.to.receive(:transaction) do
61
69
  s = SignupPresenter.new
62
70
  s.save
63
71
  end
64
-
72
+
65
73
  expect User.any_instance.to.receive(:save) do
66
74
  s = SignupPresenter.new :user => User.new(hash_for_user)
67
75
  s.save
68
76
  end
69
-
77
+
70
78
  expect Account.any_instance.to.receive(:save) do
71
79
  s = SignupPresenter.new :user => User.new(hash_for_user)
72
80
  s.save
73
81
  end
74
-
82
+
75
83
  expect SignupPresenter.new.not.to.be.save
76
-
84
+
77
85
  expect ActiveRecord::Rollback do
78
86
  ActiveRecord::Base.stubs(:transaction).yields
79
87
  User.any_instance.stubs(:save).returns(false)
@@ -81,72 +89,100 @@ Expectations do
81
89
  s = SignupPresenter.new :user => User.new(hash_for_user)
82
90
  s.save
83
91
  end
84
-
92
+
85
93
  expect ActiveRecord::Base.to.receive(:transaction) do
86
94
  s = SignupPresenter.new
87
95
  s.save!
88
96
  end
89
-
97
+
90
98
  expect User.any_instance.to.receive(:save!) do
91
99
  s = SignupPresenter.new
92
100
  s.save!
93
101
  end
94
-
102
+
95
103
  expect Account.any_instance.to.receive(:save!) do
96
104
  User.any_instance.stubs(:save!)
97
105
  s = SignupPresenter.new
98
106
  s.save!
99
107
  end
100
-
108
+
101
109
  expect ActiveRecord::RecordInvalid do
102
110
  SignupPresenter.new.save!
103
111
  end
104
-
112
+
105
113
  expect SignupPresenter.new(:user => User.new(hash_for_user)).to.be.save!
106
-
114
+
107
115
  expect SignupPresenter.new.to.be.respond_to?(:user_login)
108
116
  expect SignupPresenter.new.to.be.respond_to?(:user_password_confirmation)
109
117
  expect SignupPresenter.new.to.be.respond_to?(:valid?) # just making sure i didn't break everything :)
110
-
118
+
111
119
  expect User.create!(hash_for_user).not.to.be.login_changed? do |user|
112
120
  s = SignupPresenter.new(:user => user)
113
121
  s.update_attributes :user_login => 'Something Totally Different'
114
122
  end
115
-
123
+
116
124
  expect SignupPresenter.new(:user => User.create!(hash_for_user)).to.receive(:save) do |s|
117
125
  s.update_attributes :user_login => 'Something'
118
126
  end
119
-
127
+
120
128
  expect 'Something Different' do
121
129
  s = SignupPresenter.new
122
130
  s.update_attributes :user_login => 'Something Different'
123
131
  s.user_login
124
132
  end
125
-
133
+
126
134
  # this is a regression test to make sure that _title is working. we had a weird conflict with using String#delete
127
135
  expect 'something' do
128
136
  s = SignupPresenter.new :account_title => 'something'
129
137
  s.account_title
130
138
  end
131
-
139
+
132
140
  expect String do
133
141
  s = SignupPresenter.new
134
142
  s.save
135
143
  s.errors.on(:user_login)
136
144
  end
137
-
145
+
138
146
  expect String do
139
147
  s = SignupPresenter.new
140
148
  s.save! rescue
141
149
  s.errors.on(:user_login)
142
150
  end
143
-
151
+
144
152
  expect 'Login' do
145
153
  SignupPresenter.human_attribute_name(:user_login)
146
154
  end
147
-
155
+
148
156
  # it was raising with nil
149
157
  expect SignupPresenter do
150
158
  SignupPresenter.new(nil)
151
159
  end
160
+
161
+ expect EndingWithSPresenter.new.address.not.to.be.nil?
162
+
163
+ # this should act as ActiveRecord models do
164
+ expect NoMethodError do
165
+ SignupPresenter.new({:i_dont_exist=>"blah"})
166
+ end
167
+
168
+ expect CantSavePresenter.new.not.to.be.save # it won't save because the filter chain will halt
169
+
170
+ expect ActiveRecord::RecordNotSaved do
171
+ CantSavePresenter.new.save!
172
+ end
173
+
174
+ expect 'Some Street' do
175
+ p = AfterSavePresenter.new
176
+ p.save
177
+ p.address.street
178
+ end
179
+
180
+ expect 'Some Street' do
181
+ p = AfterSavePresenter.new
182
+ p.save!
183
+ p.address.street
184
+ end
185
+
186
+ expect SamePrefixPresenter.new.to.be.respond_to?(:account_title)
187
+ expect SamePrefixPresenter.new.to.be.respond_to?(:account_info_info)
152
188
  end
@@ -19,6 +19,14 @@ ActiveRecord::Schema.define(:version => 0) do
19
19
  t.string :subdomain, :default => ''
20
20
  t.string :title, :default => ''
21
21
  end
22
+
23
+ create_table :addresses do |t|
24
+ t.string :street
25
+ end
26
+
27
+ create_table :account_infos do |t|
28
+ t.string :info
29
+ end
22
30
  end
23
31
 
24
32
  class User < ActiveRecord::Base
@@ -27,11 +35,39 @@ class User < ActiveRecord::Base
27
35
  attr_accessor :password_confirmation
28
36
  end
29
37
  class Account < ActiveRecord::Base; end
38
+ class Address < ActiveRecord::Base; end
39
+ class AccountInfo < ActiveRecord::Base; end
30
40
 
31
41
  class SignupPresenter < ActivePresenter::Base
32
42
  presents :account, :user
33
43
  end
34
44
 
45
+ class EndingWithSPresenter < ActivePresenter::Base
46
+ presents :address
47
+ end
48
+
49
+ class CantSavePresenter < ActivePresenter::Base
50
+ presents :address
51
+
52
+ before_save :halt
53
+
54
+ def halt; false; end
55
+ end
56
+
57
+ class AfterSavePresenter < ActivePresenter::Base
58
+ presents :address
59
+
60
+ after_save :set_street
61
+
62
+ def set_street
63
+ address.street = 'Some Street'
64
+ end
65
+ end
66
+
67
+ class SamePrefixPresenter < ActivePresenter::Base
68
+ presents :account, :account_info
69
+ end
70
+
35
71
  def hash_for_user(opts = {})
36
72
  {:login => 'jane', :password => 'seekrit' }.merge(opts)
37
73
  end
@@ -21,7 +21,7 @@ module AttributeFu
21
21
  def fields_for_associated(associated, *args, &block)
22
22
  conf = args.last.is_a?(Hash) ? args.last : {}
23
23
  associated_name = extract_option_or_class_name(conf, :name, associated)
24
- name = associated_base_name associated_name
24
+ name = associated_base_name(associated_name, conf[:object_name])
25
25
 
26
26
  unless associated.new_record?
27
27
  name << "[#{associated.new_record? ? 'new' : associated.id}]"
@@ -53,8 +53,12 @@ module AttributeFu
53
53
 
54
54
  css_selector = options.delete(:selector) || ".#{@object.class.name.split("::").last.underscore}"
55
55
  function = options.delete(:function) || ""
56
-
56
+
57
+ # HACK - added by sean to allow another javascript function to be called after the removal
58
+ after = options.delete(:after) || ""
59
+
57
60
  function << "$(this).up('#{css_selector}').remove()"
61
+ function << after
58
62
 
59
63
  @template.link_to_function(name, function, *args.push(options))
60
64
  end
@@ -84,12 +88,15 @@ module AttributeFu
84
88
  opts.symbolize_keys!
85
89
  partial = opts.delete(:partial) || associated_name
86
90
  container = opts.delete(:expression) || "'#{opts.delete(:container) || associated_name.pluralize}'"
91
+
92
+ # Hack by sean
93
+ object_name = opts.delete(:object_name)
87
94
 
88
95
  form_builder = self # because the value of self changes in the block
89
96
 
90
97
  @template.link_to_function(name, opts) do |page|
91
98
  page << "if (typeof #{variable} == 'undefined') #{variable} = 0;"
92
- page << "new Insertion.Bottom(#{container}, new Template("+form_builder.render_associated_form(object, :fields_for => { :javascript => true }, :partial => partial).to_json+").evaluate({'number': --#{variable}}).gsub(/__number_/, #{variable}))"
99
+ page << "new Insertion.Bottom(#{container}, new Template("+form_builder.render_associated_form(object, :fields_for => { :javascript => true, :object_name => object_name }, :partial => partial).to_json+").evaluate({'number': --#{variable}}).gsub(/__number_/, #{variable}))"
93
100
  end
94
101
  end
95
102
 
@@ -128,7 +135,8 @@ module AttributeFu
128
135
  end
129
136
 
130
137
  private
131
- def associated_base_name(associated_name)
138
+ def associated_base_name(associated_name, object_name)
139
+ return "#{object_name}[#{associated_name}_attributes]" if object_name #HACK - Added by sean to allow attribute_fu to use prepopulated objects
132
140
  "#{@object_name}[#{associated_name}_attributes]"
133
141
  end
134
142
 
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 [name of plugin creator]
1
+ Copyright (c) 2007 [Michael Bumann - Railslove.com]
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,3 +1,9 @@
1
+ NOTE
2
+ ====
3
+
4
+ This is a customized version of the original `find_by_param` plugin. Its been simplified to take advantage of new Rails 2.2 functionality and I've also stripped out some stuff that I really didn't need. We're using this customized version in the [Spree](http://spreehq.org) commerce platform.
5
+
6
+
1
7
  FindByParam
2
8
  ===========
3
9
 
@@ -41,7 +47,7 @@ options for make_permalink:
41
47
  Issues
42
48
  =======
43
49
 
44
- * The database table must be created before you can use make_permalink
50
+ * Alex Sharp (http://github.com/ajsharp) pointed to an issue with STI. Better call make_permalink in every child class and not only in the parent class..
45
51
  * write nice docs
46
52
  * write nicer tests
47
53
 
@@ -1,4 +1,3 @@
1
- require 'iconv'
2
1
  require 'find_by_param'
3
2
  class ActiveRecord::Base
4
3
  class_inheritable_accessor :permalink_options
@@ -1,3 +1,11 @@
1
+ # This is a modified version of the original find_by_param plugin by Michael Bumann. Simplified to use Rails 2.2
2
+ # functionality and tossed out some features not worth supporting.
3
+ begin
4
+ require "active_support/multibyte"
5
+ rescue LoadError
6
+ require "rubygems"
7
+ require "active_support/multibyte"
8
+ end
1
9
  module Railslove
2
10
  module Plugins
3
11
  module FindByParam
@@ -7,89 +15,37 @@ module Railslove
7
15
  end
8
16
 
9
17
  module ClassMethods
10
-
11
-
12
- =begin rdoc
13
-
14
- This method initializes find_by_param
15
-
16
- class Post < ActiveRecord::Base
17
- make_permalink :with => :title, :prepend_id=>true
18
- end
19
-
20
- The only required parameter, is <tt>:with</tt>.
21
-
22
- If you want to use a non URL-save attribute as permalink your model should have a permalink-column to save the escaped permalink value. This field is then used for search.
23
-
24
- If your you can just say make_permalink :with => :login and you're done.
25
-
26
- You can use for example User.find_by_param(params[:id], args) to find the user by the defined permalink.
27
-
28
- == Available options
29
-
30
- <tt>:with</tt>:: (required) The attribute that should be used as permalink
31
- <tt>:field</tt>:: The name of your permalink column. make_permalink first checks if there is a column.
32
- <tt>:prepend_id</tt>:: [true|false] Do you want to prepend the ID to the permalink? for URLs like: posts/123-my-post-title - find_by_param uses the ID column to search.
33
- <tt>:escape</tt>:: [true|false] Do you want to escape the permalink value? (strip chars like öä?&?) - actually you must do that
34
-
35
- =end
18
+
36
19
  def make_permalink(options={})
37
20
  options[:field] ||= "permalink"
38
- options[:param] = options.delete(:with)
39
- options[:escape] ||= true
40
- options[:prepend_id] ||= false
41
-
21
+
42
22
  if self.column_names.include?(options[:field].to_s)
43
- options[:field_to_encode] = options[:param]
44
23
  options[:param] = options[:field]
45
-
46
- before_validation :save_permalink
47
- validates_uniqueness_of options[:param]
48
- validates_presence_of options[:param]
24
+ before_save :save_permalink
49
25
  end
50
26
 
51
27
  self.permalink_options = options
52
28
  extend Railslove::Plugins::FindByParam::SingletonMethods
53
29
  include Railslove::Plugins::FindByParam::InstanceMethods
54
30
  rescue
55
- puts "Database not available"
31
+ puts "[find_by_param error] database not available?"
56
32
  end
57
33
  end
58
34
 
59
35
  module SingletonMethods
60
-
61
- # found somewhere on the web.... don't know where... but it's from a clever guy - (done some motifications)
62
- def escape(str)
63
- return "" if str.blank? # hack if the str/attribute is nil/blank
64
- s = Iconv.iconv('ascii//ignore//translit', 'utf-8', str.dup).to_s
65
- returning str.dup.to_s do |s|
66
- s.gsub!(/\ +/, '-') # spaces to dashes, preferred separator char everywhere
67
- s.gsub!(/[^\w^-]+/, '') # kill non-word chars except -
68
- s.strip! # ohh la la
69
- s.downcase! # :D
70
- s.gsub!(/([^ a-zA-Z0-9_-]+)/n,"") # and now kill every char not allowed.
71
- end
72
- end
73
-
74
- =begin rdoc
75
36
 
76
- Search for an object by the defined permalink column. Similar to find_by_login.
77
- Returns nil if nothing is found
78
- Accepts an options hash as a second parameter which is passed on to the rails finder.
79
- =end
80
37
  def find_by_param(value,args={})
81
- param = permalink_options[:prepend_id] ? "id" : permalink_options[:param]
38
+ if permalink_options[:prepend_id]
39
+ param = "id"
40
+ value = value.to_i
41
+ else
42
+ param = permalink_options[:field]
43
+ end
82
44
  self.send("find_by_#{param}".to_sym, value, args)
83
45
  end
84
46
 
85
- =begin rdoc
86
-
87
- Like find_by_param but raises an ActiveRecord::RecordNotFound error if nothing is found. Similar to find()
88
-
89
- Accepts an options hash as a second parameter which is passed on to the rails finder.
90
- =end
91
47
  def find_by_param!(value, args={})
92
- param = permalink_options[:param]
48
+ param = permalink_options[:field]
93
49
  obj = find_by_param(value, args)
94
50
  raise ::ActiveRecord::RecordNotFound unless obj
95
51
  obj
@@ -97,22 +53,12 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
97
53
  end
98
54
 
99
55
  module InstanceMethods
100
- def to_param
101
- value = self.send(permalink_options[:param]).dup.to_s.downcase rescue ""
102
- returning "" do |param|
103
- param << "#{id}" if value.blank? || permalink_options[:prepend_id]
104
- param << "-" if permalink_options[:prepend_id]
105
- param << "#{escape_and_truncate_for_permalink(value)}"
106
- end
107
- end
108
-
109
- private
110
-
56
+
57
+ protected
111
58
  def save_permalink
112
59
  return unless self.class.column_names.include?(permalink_options[:field].to_s)
113
60
  counter = 0
114
- base_value = escape_and_truncate_for_permalink(read_attribute(permalink_options[:field_to_encode]))
115
- permalink_value = "#{base_value}"
61
+ permalink_value = self.to_param
116
62
 
117
63
  conditions = ["#{self.class.table_name}.#{permalink_options[:field]} = ?", permalink_value]
118
64
  unless new_record?
@@ -120,22 +66,12 @@ Accepts an options hash as a second parameter which is passed on to the rails fi
120
66
  conditions << self.send(self.class.primary_key.to_sym)
121
67
  end
122
68
  while self.class.count(:all, :conditions => conditions) > 0
123
- permalink_value = "#{base_value}-#{counter += 1}"
69
+ permalink_value = "#{permalink_value}-#{counter += 1}"
124
70
  conditions[1] = permalink_value
125
71
  end
126
72
  write_attribute(permalink_options[:field], permalink_value)
127
73
  true
128
74
  end
129
-
130
- def escape(value)
131
- self.class.escape(value)
132
- end
133
-
134
- #this escapes and truncates a value. default length is 100
135
- #used to escape and truncate permalink value
136
- def escape_and_truncate_for_permalink(value, length=100)
137
- self.class.escape(value)[0..length]
138
- end
139
75
  end
140
76
 
141
77
  end