The hidden plan_id field is actually set because of the call to plan.subscriptions.build method. Without that call, :plan_id hidden field within the form would be nil.
You're using the build method to set that value within the form. That way, when you call the Subscription.new method using the params hash, it will know which plan the subscription is associated with.
Got it. But in the create action, isn't he already setting this association when passing in the params hash into Subscription.new()? Doesn't the params hash contain the plan id since the form has a hidden field for the plan id (f.hidden_field :plan_id)? In other words, is he setting the association twice?
In case someone's still looking for an easy answer to searching in multiple attributes, you can set it up like the where params in scopes:
def self.search(search)
if search
find(:all, :conditions => ['first_name LIKE ? || last_name LIKE ? || company_name LIKE ?', "%#{search}%", "%#{search}%", "%#{search}%"])
else
find(:all)
end
end
Excellent and just in time. I've been stuck trying to choose between Spreedly, Chargify, Recurly etc. but they're so expensive by the time you factor in internet merchant accounts and payment gateways etc. I really want to hear more about Paypal recurring payments!
I'd love to see a future episode on advanced subjects such as failed payments, canceled subscriptions and importantly upgrades/downgrades between packages and the associated pro-rata calculations. Usually very complex stuff (in terms of business logic) but I'm sure it's a subject you can cover with relative ease given your style! :)
A couple of questions about your implementation of save_with_subscription:
1) you use save! in your implementation. Would it be better to either return the result of save, or change the name of the function to save_with_subscription!, in order to better follow conventions?
2) I noticed that you don't handle failures to save. In the real world, we would need to handle that failure by manually rolling back the subscription creation. Or is there a better way to handle this with Stripe?
I would also like to see an episode on insufficient funds and subscription cancellations. I would also like to see how you create tests for external web services like paypal, stripe or whatever.
There is no PayPal yet in my work, but it was interesting to watch this episode. One thing that bothers me though is that you skip testing part which is crucial in billing and payments. I know, the episode would be two times longer if you covered this as well but it was very scary to see you just quickly testing the stuff in a browser.
Also means you could re-use the same JS file with another project. For example if you build a merchant hosting site where each of your users can create their own merchant site hosted by you, you could change easily who the payment is going to while using the same JS file for everyone.
Some peculiarities of Ruby's parser (nothing to do with Rails). Without self, it would think you are trying to assign a local stripe_customer_token variable instead of using the implicitly defined self.stripe_customer_token= attribute writer.
That would likely trigger a Stripe::InvalidRequestError when trying to Stripe::Customer.create( card: stripe_card_token) with your faked stripe_card_token, and thus prevent saving the subscription record.
Hey guys. Delighted there's now more Railscasts loveliness each week. Yay.
I'm a little confused about what to do with application wide presenters. For example, I want to show either a "Sign In" link or a "Log Out" link depending on whether the user's logged in. This is somewhere I would normally include some logic in the view, probably the app layout and it'd be great to move it to a presenter. But which one?
I'm playing with Sorcery following your recent episode, so I have a current_user object I can inspect to determine whether anybody's logged in. But it's not referenced through a model so I don't know how to move it to a decorator. I could decorate the user model but creating an @user instance in every view feels, well, odd.
Am I correct in thinking that I could bypass the credit card payment altogether by manually setting a value to the hidden token field (using javascript console or similar before submitting)?
you are really saying something like: @subscription = Subscription.new(plan_id: id)
You are wanting an object that already has the association (to a particular Plan, in this case) set. This object is passed to the form with the association set -- so it knows how this particular Subscription object relates to a specific Plan object.
You can see that Ryan adds a stripe_customer_token to the subscription model:
rails g migration add_stripe_to_subscriptions stripe_customer_token:string
self.stripe_customer_token = customer.id sets that in the current subscription object (taken from the object returned by Stripe::Customer.create() method).
Hi Ryan,
Thanks for this amazing cast.
I was wondering if you can do another cast regarding Ebay complex database categories. Is Ancestry gem enough or should we go deeper.
Very nice recommendation! I hadn't seen stripe before and have been grudgingly testing other payment processors. This looks fantastic and very reasonable
Actually I really appreciate the effort you took to put this together Ryan, even if it came out a bit longer than expected. It's certainly not one of the easier pieces of rails integration and is a great choice for a pro episode. Many websites will still require this so it's a valuable addition!
Thank you, Ryan Bates ... beauty, even in work, speaks for itself.
I have actually viewed and coded every single episode
... yes, play+pause+type, repeat ... the ASCIIcasts really help doing this.
It kind of helps to take the 'Monday' out of Mondays.
Will there be a script or something like ASCIIcasts for the pro versions ?
This is just a thought, not a criticism, but I was wondering if it might
be possible to purchase individual pro episodes ?
I mean a pricing scheme similar to renting movies/games at one of
those redbox kiosks ... a $1 is a great price. In this area they have
really caught on at grocery stores and 7-11's ... I almost expect to
see one on my porch one day. I think a recurring payment might be
a barrier to some, especially during these troubled times ... just a thought.
i like the idea, but if i start refactoring with a decorator i come across one big problem.
if i wanna wrap a small method to a decorator like user.full_name i would have to make tons of decorators to wrap all my associations, like note.user.full_name, project.owner.full_name etc. well maybe its just realy for big view stuff. but i would love to use it also for the small parts.
Tried to upgrade my blog from 3.0.9 to 3.0.10 and 3.1.0 like you did in the tutorial but I got the most stupid error ever with no proper message, so I have no idea whatsoever of what's going on:
Started GET "/admin" for 127.0.0.1 at 2011-10-10 12:28:33 +0300
ArgumentError (wrong number of arguments (3 for 2)):
This could be b'cos to_json returns values within { } and the token inputs js looks for [{ ...}] format, this is my guess. Thanks for posting this , wasted 3 hrs on this :)
I followed this blog entry to load custom validators from lib/validators. I also named the EmailFormatValidator to EmailValidator. It makes more sense to me. :email => true. Great screencast as always, just needs the little update about loading validators. :)
The hidden plan_id field is actually set because of the call to
plan.subscriptions.build
method. Without that call, :plan_id hidden field within the form would be nil.You're using the
build
method to set that value within the form. That way, when you call theSubscription.new
method using the params hash, it will know which plan the subscription is associated with.Got it. But in the create action, isn't he already setting this association when passing in the params hash into Subscription.new()? Doesn't the params hash contain the plan id since the form has a hidden field for the plan id (f.hidden_field :plan_id)? In other words, is he setting the association twice?
When switching to spork I encountered a string of errors like this:
This happened when using the
gem 'growl_notify'
. Switching my Gemfile over to just usegem 'growl'
fixed this error.I haven't used either, but based on their prices i would recommend Stripe
Great work, i've been using active merchant fork supporting PPR for express checkout, and this does seem like a much lighter solution.
Very nicely done :)
Is something like this what was used for the railscasts pro? I thought my statement showed something other than paypal..
(may we ask what was used for this sites payments?)
really like the coffee script stuff in this, I learned a lot
In case someone's still looking for an easy answer to searching in multiple attributes, you can set it up like the where params in scopes:
Thats why paypal provides a sandbox :)
Excellent and just in time. I've been stuck trying to choose between Spreedly, Chargify, Recurly etc. but they're so expensive by the time you factor in internet merchant accounts and payment gateways etc. I really want to hear more about Paypal recurring payments!
I'd love to see a future episode on advanced subjects such as failed payments, canceled subscriptions and importantly upgrades/downgrades between packages and the associated pro-rata calculations. Usually very complex stuff (in terms of business logic) but I'm sure it's a subject you can cover with relative ease given your style! :)
Thanks for a great screencast!
Since jQuery 1.6 you should use
prop()
method to set boolean attributes:$('input[type=submit]').prop('disabled', true)
Thanks.
A couple of questions about your implementation of
save_with_subscription
:1) you use
save!
in your implementation. Would it be better to either return the result ofsave
, or change the name of the function tosave_with_subscription!
, in order to better follow conventions?2) I noticed that you don't handle failures to
save
. In the real world, we would need to handle that failure by manually rolling back the subscription creation. Or is there a better way to handle this with Stripe?I would also like to see an episode on insufficient funds and subscription cancellations. I would also like to see how you create tests for external web services like paypal, stripe or whatever.
There is no PayPal yet in my work, but it was interesting to watch this episode. One thing that bothers me though is that you skip testing part which is crucial in billing and payments. I know, the episode would be two times longer if you covered this as well but it was very scary to see you just quickly testing the stuff in a browser.
Hmm... Personally I think I would have added the erb-preprocessor to the coffeescript-file and referenced the constant through an erb block:
Sign up here
https://stripe.com/help/global
Maybe it will encourage them to speed things along :)
Thanks for accommodating us non-US users with this cast. Hopefully Stripe will do too soon.
Also means you could re-use the same JS file with another project. For example if you build a merchant hosting site where each of your users can create their own merchant site hosted by you, you could change easily who the payment is going to while using the same JS file for everyone.
Some peculiarities of Ruby's parser (nothing to do with Rails). Without
self
, it would think you are trying to assign a localstripe_customer_token
variable instead of using the implicitly definedself.stripe_customer_token=
attribute writer.That would likely trigger a
Stripe::InvalidRequestError
when trying toStripe::Customer.create( card: stripe_card_token)
with your fakedstripe_card_token
, and thus prevent saving the subscription record.Hey guys. Delighted there's now more Railscasts loveliness each week. Yay.
I'm a little confused about what to do with application wide presenters. For example, I want to show either a "Sign In" link or a "Log Out" link depending on whether the user's logged in. This is somewhere I would normally include some logic in the view, probably the app layout and it'd be great to move it to a presenter. But which one?
I'm playing with Sorcery following your recent episode, so I have a current_user object I can inspect to determine whether anybody's logged in. But it's not referenced through a model so I don't know how to move it to a decorator. I could decorate the user model but creating an @user instance in every view feels, well, odd.
Any guidance would be gratefully received.
Am I correct in thinking that I could bypass the credit card payment altogether by manually setting a value to the hidden token field (using javascript console or similar before submitting)?
I would love to see that as well.
Unfortunately many of us have no option to use stripe. So this is a great resources for people outside the US.
Thanks ryan.
Thank you for releasing this screencast about PayPal recurring billing.
I am also interested in a follow-up episode re handling insufficient funds, changing the plan or canceling the subscription.
Thank you! Looking forward to the episode about handling insufficient funds, end of subscription and possibly the case when a user changes his plan.
@1: Because this makes it easily configurable from, for example yml file.
@3: plan.subscriptions.build is equivalent of Subscription.new(plan: plan)
Which is better to use? Braintree or stripe?
Regarding question 3...
It has to do with the model associations.
When you say:
@subscription = plan.subscriptions.build
you are really saying something like:
@subscription = Subscription.new(plan_id: id)
You are wanting an object that already has the association (to a particular Plan, in this case) set. This object is passed to the form with the association set -- so it knows how this particular Subscription object relates to a specific Plan object.
see: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
meltzerj,
Regarding question 2...
You can see that Ryan adds a stripe_customer_token to the subscription model:
rails g migration add_stripe_to_subscriptions stripe_customer_token:string
self.stripe_customer_token = customer.id
sets that in the current subscription object (taken from the object returned by Stripe::Customer.create() method).Hope that helps!
Hi Ryan,
Thanks for this amazing cast.
I was wondering if you can do another cast regarding Ebay complex database categories. Is Ancestry gem enough or should we go deeper.
Thanks anyway!
Thanks!
A couple of questions:
Why do you pass the API key into the meta tag and grab it in the javascript instead of just hard coding it into the javascript?
In the "save_with_payment" instance method, why do you reference "self" when assigning the customer id to an attribute of the instance.
In the new action of the subscriptions controller, why do you need "@subscription = plan.subscriptions.build"?
Great video on a great service. For those outside the US, know that Stripe is working on it. :)
Stripe on HackerNews
I cannot believe how easy Stripe has made ecomm for developers! Thanks for the intro to this killer offering.
Very nice recommendation! I hadn't seen stripe before and have been grudgingly testing other payment processors. This looks fantastic and very reasonable
Just what I was about to use! Always on the ball.
TL;DR Use Stripe :)
Actually I really appreciate the effort you took to put this together Ryan, even if it came out a bit longer than expected. It's certainly not one of the easier pieces of rails integration and is a great choice for a pro episode. Many websites will still require this so it's a valuable addition!
Can't use it here, oh well :(
Ahhhhhhhhhhhhhhh only US :(
Thank you, Ryan Bates ... beauty, even in work, speaks for itself.
I have actually viewed and coded every single episode
... yes, play+pause+type, repeat ... the ASCIIcasts really help doing this.
It kind of helps to take the 'Monday' out of Mondays.
Will there be a script or something like ASCIIcasts for the pro versions ?
This is just a thought, not a criticism, but I was wondering if it might
be possible to purchase individual pro episodes ?
I mean a pricing scheme similar to renting movies/games at one of
those redbox kiosks ... a $1 is a great price. In this area they have
really caught on at grocery stores and 7-11's ... I almost expect to
see one on my porch one day. I think a recurring payment might be
a barrier to some, especially during these troubled times ... just a thought.
Thank you again.
Why should it? HAML is just templating language so you would just use same methods in HAML syntax from the view.
i like the idea, but if i start refactoring with a decorator i come across one big problem.
if i wanna wrap a small method to a decorator like user.full_name i would have to make tons of decorators to wrap all my associations, like note.user.full_name, project.owner.full_name etc. well maybe its just realy for big view stuff. but i would love to use it also for the small parts.
+ cancan not liking it :)
Very nice. I've been wanting to get rid of helpers in our application for a quite a while and this looks like a very clean and elegant solution.
Any suggestions on how to write a presenter for a collection of object, like for an index view?
Tried to upgrade my blog from 3.0.9 to 3.0.10 and 3.1.0 like you did in the tutorial but I got the most stupid error ever with no proper message, so I have no idea whatsoever of what's going on:
Started GET "/admin" for 127.0.0.1 at 2011-10-10 12:28:33 +0300
ArgumentError (wrong number of arguments (3 for 2)):
Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.1.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.1.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.0ms)
Rendered c:/Ruby192/lib/ruby/gems/1.9.1/gems/actionpack-3.1.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.0ms)
Help?
Why not use the presence method to make the avatar_name method a 1-liner?
Try running it like this:
Try replacing it with the following:
This could be b'cos to_json returns values within { } and the token inputs js looks for [{ ...}] format, this is my guess. Thanks for posting this , wasted 3 hrs on this :)
Done,
but doesn't seem to work anyway.
My last working gems matrix is :
bson (1.4.0)
bson_ext (1.4.0)
mongo (1.4.0)
mongoid (2.1.1)
mongoid-rspec (1.4.4)
mongoid_taggable_with_context (0.7.2)
as soon as I upgrade to mongoid 2.1.2,
kaminari '0.12.4' First/Previous/Next/Last in the view don't show up anymore ...
I followed this blog entry to load custom validators from
lib/validators
. I also named theEmailFormatValidator
toEmailValidator
. It makes more sense to me.:email => true
. Great screencast as always, just needs the little update about loading validators. :)Here's the snippet:
config/application.rb