Chronicling my experiences with ruby on rails, web application development/management.

Saturday, November 29, 2008

Updating Rails app from 2.0.2 to 2.2.2

Ahh the fun begins. In this post you will find the 'gotchas' I had with updating an existing established app from rails version 2.0.2 to the new version of 2.2.2.


Cache_template_extensions Error


Here is the partial stack error


/Users/nerb/.gem/ruby/1.8/gems/rails-2.2.2/lib/initializer.rb:530:in `send': undefined method `cache_template_extensions=' for ActionView::Base:Class (NoMethodError)


Solution! - There was mention of an error at line 15 of my environment.rb file. I went to the environments/development.rb and deleted the line
config.action_view.cache_template_extensions = false I read on the interweb that this cache_template_extensions no longer is used or is has been deleted.


Now maybe the time to update Plugins.


As a public service, I wonder if now is the time to update your plugins, if it's been awhile. Some may never change (Acts_as_tree), but some change fairly rapidly (Restful_authentication).


For Restful Authentication, I know there is a new password feature that doesn't jive with the old passwords. However, since I also need to update this plugin, I wonder if it's better to scrap the --old-passsword flag and investigate why the new way is better? Could it be that I may change all of the current user's passwords on my site? Only if there is a dang good reason. A dang good one.

Sunday, November 23, 2008

Acts as ferret : only have one instance per development computer...

Symptoms


I kept getting this stupid error
(druby://localhost:9010) /Users/nerb/.gem/ruby/1.8/gems/activesupport-2.1.2/lib/active_support/dependencies.rb:279:in `load_missing_constant': uninitialized constant Browser (NameError)


How to solve this error


Basically I got this error because Acts as ferret was running in another app on my development box. Just do a simple script/ferret_server stop in the OLD app. Return to the new app and start the ferret server by doing script/ferret_server start


Hell, i thought it had to do with my recent updating of rails to 2.2.2, however, it did not.

Friday, November 21, 2008

Serialize... what the #@#&%!!?

Ok. For all my loyal readers, here is one thing that just wasn't jiving for me.

Serialize is Killing me!



Serialize :column is code that should be put into your model.

What that little line does is save whatever code you save to that column as yaml. Oh and make sure :column is a type :string.

Without doing anything to the column upon saving, this is an example of what could be in your db.

column: "--- \n- subscription\n- membership\n"

Now supposedly, all i have to do to use this string of yaml is to call it like i normally would, say in a for loop, and it 'un yaml fies' itself. No such luck.

What tricks do you guys use when you are serializing? i'll take any help here.

Update 11-28-08


As my exploits from Railsforum will show, i got it to work finally. Thanks to rob-wtf from Railsforum for the help!

P.s. I bookmarked their paperclip article... it's pretty good. Well minus the windows stuff.

Sunday, November 16, 2008

Recurring Payments using PayPal Express and Active Merchant

I needed a payment solution that took recurring payments for my rails app. Most of the tutorials out there use either a US based merchant account provider, or are based in the UK. I guess canadians are out to lunch. Oh, and what's worse was that none of them really touched on subscription based models, or as it turns out, recurring payments.


Caveat: Now i am not here to take credit for what I'm about to write. I only write this post as a 'mashup' of two great men and their tutorials on the subject. I just took these two tutorials and used the good from both of them to come up with what you are about to read.


The fine men who authored these posts


Cody Fauser - Active Merchant extraordinaire


Cody is from all accounts the man, if not only the public face, of Active Merchant. His Active Merchant Peepcode pdf (a must read and only 9 bucks!) is the go to guide for learning all about Active merchant from the man himself.


Jon Baker - Paypal Express Recurring Payments add on for Active Merchant Plugin


From his homepage"As well as leading the Rich internet Application at Trigger Software Ltd, he is CEO and Entrepreneur of Vibrant Apps a small company based in Cornwall that makes useful and useable apps."


On with the show...


Basically, i used the framework from Cody's Paypal Express Payments with Active Merchant for my controller/view actions and I used the plugin extension from Jon's post Paypal Express Recurring Payments using Active Merchant.


The sum of these two parts became what i needed to get a basic subscription for my app, and now for you too.


Gimme the High Level overview nerbie69!


Will do. Oh, and i assume you already know how to create a rails app, and that you are following usual rails behaviour and will know that everything in here is based off of being inside your rails app, when you run any code. This tutorial is probably above beginners so i assume anyone reading this kinda knows what they are doing and are just stuck at how to implement subscription based models easily.



  1. Create your Paypal Sandbox developer account and instantiate an API credential from your seller account

  2. Install Active Merchant from github

  3. Insert Jon Baker's Paypal express Recurring Payments nv . rb file in your new Active Merchant plugin

  4. Create your controller and views

  5. Test your new subscription model in your browser

  6. Pinch yourself... it was that easy.


So there you have it. It's the simple steps version of what you are about to do.


Step One - Create your paypal sandbox developer account


Go to https://developer.paypal.com to set up your paypal developer account.
You can find better instructions on the developer site, but it isn't too hard and out of scope for this tutorial. However, make sure you get the api credentials from the Seller account(_biz). I.e., you must log in as the seller, in the sandbox, and follow Cody's instructions on how to set up the API.


Step Two - Install Active Merchant


Go to github and install the Active Merchant plugin: script/plugin install git://github.com/Shopify/active_merchant.git I'm using the plugin here because it's easier to add a file, which is the next step.


Step Three - Adding the paypal_express_recurring_nv.rb file to Active Merchant


Download or copy and paste the following file paypal_express_recurring_nv.rb and put it in the following directory: /vendor/plugins/active_merchant/lib/active_merchant/billing/gateways/

The plan is to get this into active merchant in a future release. We all have a part in making sure this happens, by emailing activemerchant's maintainers and saying how helpful this was. Plus then we can fix any bugs and extend to make it even better.


Step Four - Create your controller and views in your rails app


From here on out is where i mashed the two tutorials together. First create your controller and views: script/generate controller subscriptions index confirm cancel error


Now add the following, as Cody says, to the top of your application.rb controller
include ActiveMerchant::Billing
Also, don't forget to put your ActiveMerchant into test mode, as outlined in his tutorial.


I'll paste the full controller code, so you can see it in all it's glory. Notice, as Cody says, we didn't need a view for checkout, so that is why we didn't add 'it', to the generate code above.class SubscriptionsController < ApplicationController
def index
end

def cancel
end

def error

end

# Confirmation step is the actual step that sends money.
def confirm
response = gateway.create_profile(999, params[:token], :reference => "34")
if !response.success?
@message = purchase.message
render :action => 'error'
return
end
end
# The checkout method used to pass the values to paypal. The description is shown to the user in their paypal account.
def checkout
setup_response = gateway.setup_agreement("Monthly subscription fee $9.99 USD",
:return_url => url_for(:action => 'confirm', :only_path => false),
:cancel_return_url => url_for(:action => 'index', :only_path => false)
)
redirect_to gateway.redirect_url_for(setup_response.token)
end
private
#Here's the gateway info.
def gateway
@gateway ||= PaypalExpressRecurringNvGateway.new(
:login => 'Seller_232323455_biz_api1@site.com',
:password => 'W32RW53TE64Y7',
:signature => 'A90EWQRLSDA0SA.SAD0FASWEQ4ls0sl20S0SLD0.223.w'
)
end
end


Views


The views are easy to setup and obviously could say anything. Here is what i did, to get a generic subscription message setup:


# Index.html.erb:

< h1 >Site Subscription< /h1>
< p >Thank you for your decision to subscribe to this site.


< p >Your order total is $9.99 / month


< p >
< % = link_to image_tag('https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif'), :action => 'checkout' % >
< / p >

The error messages can stay the same as what cody has, i believe.


The confirm view really doesn't have to say anything other then Thanks! All the magic happens in the controller when the response comes back. I know that i am probably going to add my own app specific controller functions to this confirm, such as creating their profiles and setting certain site variables, now that they have subscribed to become 'one of the cool kids'


Step Five - Test in your browser and revel at your genius


That heading says it all.


Thanks for reading and enjoy.


I hope that you enjoyed this little tutorial. Subscription handling hasn't been easier thanks to Jon Baker, active merchant and all their hard work.

Saturday, November 15, 2008

The tail of two admin panels

What are the most popular ways of handling an admin area in a web application?  Since i develop in rails, my focus will be on rails, however i do love the built in admin panel from django.  Excuse me DHH for I have sinned....

Admin Concept #1 - separate namespace in url (i.e., /admin)

When adding an admin namespace, the following steps should be followed:
  1. change routes
  2. setup new directory structure in app/
  3. change views to reflect new namespace
  4. secure access to the new admin namespace
1. Change your routes to reflect the new namespace.  for instance:
 map.namespace :admin do |admin|
    admin.resources :posts
    admin.resources :categories
    admin.resources :forums
    admin.resources :products
  end
Just for fun, run rake routes in  your app, and look at all of your new lovely routes!

2. Include a new admin directory under your app/controller, app/views and app/helpers.  E.g., app/controller/admin/nameofcontroller.rb.

You will need to change the first line of your code to read: class Admin::YourController < ApplicationController

Any redirects in your controller code must be changed to reflect your new namespace.  simply replace your existing @variable with  [:admin, @your_variable] in the redirect.  This code will redirect to the proper show method.

3.  For any new or edit views, you need to change your form_for to reflect your new namespace as well.  Changing the @variable again to reflect the new [:admin, @variable] should do the trick in most cases.  

Also, your routes have changed, so you will need to change your restful routes in all of your new admin/model views.  Usually you only need to add "admin_" to the existing route.  e.g., posts_path would become admin_posts_path.

Concept #2 - inline administration.  

Allows users to administer their site based on their user Id.  If the user is set to admin in the database, then more options appear on their profile.

That user would then have access to /settings, for instance, because of their admin status.

The Settings model would be set up as usual, i.e., no namespace needed, but a before_filter would be used to allow access only to that admin user.  

Question:  Is there a third concept?  What other ways can be used to allow for an admin "area"? Please post your comments, as I would love to hear your thoughts.