I'm trying to add an extra step to my Spree 1.2 store which will allow a customer to create a subscription. I've inserted the step, and rendered the correct view, but when the user clicks 'save and continue' the next step is rendered, but nothing is actually saved.
I understand that I need to add a state_callback, but I'm not sure how to do this and the Spree documentation is very lacking around this (presumably because it's quite new)
At present I've got the following in my extension:
models/spree/order_decorator.rb
Spree::Order.class_eval do
belongs_to :subscription
accepts_nested_attributes_for :subscription
# This doesn't appear to be called
Spree::Order.state_machine.after_transition :from => :subscription,
:do => :valid_subs?
checkout_flow do
go_to_state :address
go_to_state :subscription
go_to_state :payment, :if => lambda { |order| order.payment_required? }
go_to_state :confirm, :if => lambda { |order| order.confirmation_required? }
go_to_state :complete
remove_transition :from => :delivery, :to => :confirm
end
end
Not entirely sure that accepts_nested_attributes is necessary, but my dev approach for this has been trial and error so far, so it ended up staying there.
In models/subscription.rb
class Subscription < ActiveRecord::Base
attr_accessible :start_date, :frequency
belongs_to :user
has_many :orders
has_many :products
validates :start_date, :frequency, :presence => true
def schedule
...code that returns a list of dates rendered on FE...
end
private #----
... some methods used in schedule ...
def valid_subs?
binding.pry # never called
end
def after_subscription
binding.pry # never called either...
end
end
views/spree/checkout/_subscription.html.erb
<h1><%= t(:"subscription.title") %></h1>
<div class="columns alpha six" data-hook="subscription_calendar_fieldset_wrapper">
<fieldset id="subscription_calendar" data-hook>
<%= form.fields_for :subscription_picker do |subscription_picker| %>
<legend><%= t(:"subscription.first_delivery") %></legend>
<%= render :partial => 'subscription/picker' %>
<% end %>
</fieldset>
</div>
<div class="columns omega six" data-hook="subscription_dates_fieldset_wrapper">
<fieldset id="subscription_dates" data-hook>
<legend align="center"><%= t(:"subscription.next_deliveries") %></legend>
<div class='dates'></div>
</fieldset>
</div>
<div class="form-buttons" data-hook="buttons" style='clear:both;'>
<%= submit_tag t(:save_and_continue), :class => 'continue button primary' %>
</div>
views/subscription/_picker.html.erb
<div class='row'>
<label for="subscription_frequency">Occurs every:</label>
<% frequency_options = [["2 Weeks", 14], ["3 Weeks", 21], ["Month", 30], ["2 Months", 60], ["3 Months", 90]] %>
<%= select(:subscription, :frequency, options_for_select(frequency_options, 30), {}) %>
</div>
<div id="start-date-picker" class="calendar"></div>
<%= hidden_field(:subscription, :start_date, {value: (DateTime.now + 14).to_date.iso8601}) %>
... JS that creates the calendar ...
On clicking 'save and continue' I see the following params sent:
{
"utf8" => "✓",
"_method" => "put",
"authenticity_token" => "...BLAH...",
"subscription" => {
"frequency" => "30",
"start_date" => "2012-11-17"
},
"commit" => "Save and Continue",
"controller" => "spree/checkout",
"action" => "update",
"state" => "subscription"
}