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

Friday, December 26, 2008

3 reasons to hate your new iphone

As much as I'd like to say I'm 100% happy with my iphone, i must confess that I am not 100% happy with the iphone at all. The post that follows outlines the three reasons why I am not too happy with my iphone:

  1. You MUST jailbreak your iphone, in order to do anything cool with it
  2. Lack of bluetooth functionality when synced to macbook
  3. Apple's general malaise with bending over to the Telco's



In Canada, did you know that you are allowed to tether your iphone to your laptop. It's a selling feature to idiots like me who commute and aren't always at a wireless connection, and the thought of 3G surfing to improve your ruby on rails app got you off, big time.


The one little wee bit of information no one told you, until you shelled out the money and signed the contract, was that unless you jailbreak your iphone, Apple doesn't have a legal app to allow you to connect via bluetooth to your laptop. It's this lack of Tethering Ability that burnt my britches. I feel it's the man stain on an otherwise pristinely made bed, and i was told to sleep in it.


Now, why must a consumer be forced to jailbreak an iphone, when HE/SHE doesn't want to. I have no desire to do anything like this, nor should a consumer be asked to. He/she gets home, clicks the App Store app and prays to find a tethering app. He/she doesn't. He/she's choice: Jailbreak and risk bricking the phone or surf via Safari on iphone instead of being able to git push from your macbook, which is what i want to do in the first place.


One company had balls. NullRiver. I used their MediaLink app to connect to my PS3. Really good stuff, cause it just works. However, at last check (story Sept 13, 2008) they had their app pulled down from the App store by Apple.


Lack of bluetooth functionality when synced to macbook


Seriously, when you sync up your iphone to your macbook/imac and get that going, did you know that there is nothing you really can do through bluetooth? Maybe in the future, there will be skads of things to do, but generally, you can't do sh!t out of the box, legally.


Users of the "lesser" phones may be shocked to hear that you can't even file transfer via bluetooth from your macbook to your iphone. I believe my first samsung in 2000 had that ability.


Apple's general malaise with bending over to the Telco's


Now i'm a pretty loyal Apple customer. I've got a whole family on imac's or macbooks, a few on iphones, one on AppleTV even. I'm no fanboy who makes the trip to hear Steve Job's speak at MacWorld, I've never read an apple based blog nor do i have an account on ehmac either, but i do troll on the #mac channel often, in IRC. So my heart is with Apple. Linux was too nerdy for me, windows... is... well, windows, so Apple is the only OS that i can tolerate, have fun with and still feel secure. I also like their attitude. Here we are. like it or not, this is Apple. You don't like it, that's fine, there are alternatives out there for you.


So how can a company with this hipster attitude, take it large from a couple of stupid Ma Bell castaway TeleCom companies? Or worse, a Canadian provider!?!?! Grow a set of balls, force these babies to allow their users to surf the 3G network via their laptop, bluetoothily through their iphone. For the amount of people that would do it, and i doubt it would be that many, as most people surf walking in a mall or at a friends house when they say "Hey, look i got an iphone and i can surf for porn from your bathroom!"


So what can be done nerbie69?


I'm glad you asked. Nothing can be done, except get NullRiver's app back onto the AppStore. There is no reason for it not to be there. Also, make sure it is priced around the $29 - $49 mark. People are nothing but cheap and this price point will allow only those who really need it to buy it.


The Telco relationship won't change. Money grubbing won't change, but Apple you can price the NullRiver app accordingly so that you keep your loyal fans happy and still save face with the skidmarks from the Telco world who are trying too desperatley, like an actress getting her 12 face lift, to keep their looks and cool.

Saturday, December 20, 2008

Solved: ApplicationController has been removed from the module tree error.

A copy of ApplicationController has been removed from the module tree but is still active!
You got this error... and now you don't know what to do. Well i can offer a suggestion or two on how to fix it.

Symptoms


You may be trying to update a plugin that is conflicting with ApplicationController. You'll also notice that this error happens when you try to reload the same page, or even move a different view within the same directory. For instance, if you load plugin/index and the try to reload OR go to another link say plugin/new, you get this error.


Hit me nerbie69! Solve my problems


Well dude, you got way too many for me to solve, but this one is on me.


All douchery aside, i solved my error by deleting some of the leftover cruft of having a generator plugin, that i converted into a engines based plugin. github nerbie69/railstat plugin check out the forked project for the current generator based script.


#OLD code
require_dependency 'path_tracker'

class RailStatController < ApplicationController
include PathTracker

before_filter :extract_subdomain
....


#new code notice the difference
class RailStatController < ApplicationController
unloadable
include PathTracker

before_filter :extract_subdomain
...



Since ApplicationController is an unloadable class, we too had to match it's unloadability in our app/controllers directory of our engines based plugin. Also, we don't need the require statement, as you do when you are using a generator plugin, if you are referencing the lib directory. The engines takes care of that for you too.


Wrap it up Johnny!


Ok, engines rock. Also, you can apply this code to any of these stupid errors you might get in the future for other controllers and plugins.


Sources: rails trac from 2006.

Tuesday, December 16, 2008

Rails Engines are awesome!!!!

Some of my loyal fans may be shocked to know that i just tried the Rails Engines plugin. Officially titled engines plugin on github.


So easy, and exactly as advertised


Sometimes, try as we may, things aren't always as advertised in this community of ours. So it is a good when things go exactly as planned


Instructions on using the plugin are well written in the README, so i won't bore you with those details, but if you have ever wanted to make a plugin that had the same familiar structure as your rails app', then this is for you. All you need to do is create a plugin and then add the same app directory structure in the root folder of the plugin.


Predictions


Theoretically you can make all of your controller, models and views as plugins, making your app act almost like it's own SAAS appliance. If you have a generator style'd plugin, there is no reason not to use engines. Less coding for you, the plugin creator.


Examples of Hot Rails Engines Action (HREA?)


In fact, i just put the finishing touches on my fork of the rails stat plugin, that was purely a generator script, basically. Now in my forked version, the engines plugin takes care of generating static code within an app. And that is pretty frickin cool.

Saturday, December 13, 2008

Working with Generators in Rails - Lessons Learned the hard way.

I'm updating a plugin that works in Rails 2.2.2 development, yet borks in a production site using 2.1.0.

undefined method `render' for # Rails::Generator::Commands::Create:0x7fdf1caaa2c8


right now, Here is what the problem was


in my generator script i had the usual code
m.template "app/views/rail_stat/hits.rhtml", "app/views/rail_stat/hits.rhtml"
m.template "app/views/rail_stat/lang.rhtml", "app/views/rail_stat/lang.rhtml"

Now inside of hits.rhtml is the following line
< %= render :partial => 'menu' % >

For some reason the render part fudges everything up. if i delete that line, the files go through with no problem.


Solution


When generating erb templates, the Rails::Generator needs to use an extra percentage sign whenever you call specific erb calls. For instance, i only had used < %= render :partial => 'menu' % > but i should have used < %%= render :partial => 'menu' % >
Again, notice the extra % percentage sign in the second code bit. I'm sure there may be a better reason but the second % sign acts almost as a buffer and tells m.template to print the erb code in the new file? Again, that may be too simplistic of an answer, but that is what it seems like to me.

Tuesday, December 9, 2008

Finally. Theme_Support fully Working in Rails 2.2.2

I feel like singing. That is how happy i am.


Theme_support plugin for rails is fully working in Rails 2.2.2


I'll work with jystewart from github to get the fix onto his version, as that is what i got to work. Here is the link to Theme_support on github. Alegria!

Friday, December 5, 2008

Transferring an existing app to a new server

Let the good times roll gents. Rick Okasik and the cars once sang that song about this exact moment in time. The day I transferred my existing ruby on rails site from a shared host to slicehost.


Preamble - Reasons why, etc...


My shared hosting account at a2 has come to an end. They have been having a couple of days worth of outages here and there. Nothing too bad, usual disk failure kinds of stuff, but what really got my goat was this. A bug in cpanel that didn't allow the mongrel server to restart. So my site would be down for an eon, because they restarted the server or apache or something (never got straight answers). Now i'm a patient guy, but in terms of my website as a business, they were messing with my livelyhood. Good intentions or not, it sucked for that reason.


So the time has come to grow up and move to slicehost. I've tried Linode but i prefer slicehost. Both really offer the same principle offerings and are strictly/typically linux based servers, so i liked these two. But for some reason, slicehost resonated more with me. Just a thing i have, no fault of anyones.


Steps involved in transferring an existing app to a new server


I'll be chronicling my journey through transferring a rails app from a shared host to a VPS like slicehost. Here are the steps I took to move the server:

  1. Backed up MySQL database on old server

  2. Ftp'd backup db to new server

  3. Copied app code to new server

  4. Imported DB onto new server

  5. Fixed app settings to let it run properly, such as action mailer, etc.

  6. Updated DNS records to reflect the switch.


For the record, i already have a working passanger/mail system/rails stack on slicehost. I will chronicle what I needed to do to get this to work. However, your mileage may vary and if you screw up anything, even because of my instructions, i'm sorry, but that's on you and i won't and can't be held responsible. You've been warned.


Good, got that crap out of the way, on with the show.


Export Mysql database from old server


I followed this Slicehost article on exporting and importing db's. It was pretty easy so far.


Zip code on OLD server


As i'm using the command line for all/most of this transfer, a great resource for zipping files was About.com. Although not as sexy to use, it had all i needed. I used the following commands:

zip -r app_new app -x \*.log

Notice the -x which will exclude your stupidly huge log files. I need to find a better way to manage them.

By the way i went from 40mb zip file with logs to 10.5mb zip file. need i say more

FTP code and .sql file to New Server


No explanation really needed here. I used ftp from old server to my desktop and then i used sftp onto new server at slicehost. Your mileage may vary, but you get the idea.


Unzip code into new /var/sites/ directory


I unzipped the code into a web-applicaton chmod'd directory.
unzip app.zip


Import DB.sql file into the NEW Server


The Slicehost article on exporting and importing db's again came in handy here. So easy, so good.


Setup your new DB user


I ended up creating a new user, just to be safe. Probably no need to do this, as you can keep the same one from your old server, but just in case. I just followed this Slicehost article on creating Mysql users. Grant All privleges, as he shows in the article.


install all your outstanding gems


Since i forgot which gems i need, and I am not ready to upgrade this app to 2.2.2 yet, as it's in rails 2.0.2, I need to go to the old server, and pull off all the gems i used, and reinstall them on the NEW server. Once this is done, we can setup the config files for actionmailer and the db itself.

Well it looks like it's the old rmagick gem that was the troublsome one. Thanks to enrailed.net for helping me out with this one. It's weird to me how i followed the same steps using aptitude and I got an error, but if i use apt-get, i was fine... whatever eh! Oh and gem install rails -v 2.0.2 just hung there, so i said screw it, and i'm going to go with the one i have on there 2.1.2.

Lastly for all UBUNTU Hardy users that don't know.... update your ruby gems. the POS that is shipped with that ubuntu version will disappoint you, if it hasn't already. Thanks to Mike's post here at a fresh cup blog you'll find out how more. Simply put, just run
sudo gem install rubygems-update
sudo update_rubygems



Update Config and database files


so you'll need to update anything in your config/environment.rb file that was server specific, such as actionmailer settings. Also, make sure your config/database.yml file reflects your NEW database.


Update your server settings


I, like most of the free rails world, are now using passanger to serve our app. If you aren't, run, don't walk, to the nearest passanger downloading station and fricking do it! Mongrel's time has passed, much like zed shaw's rants. It meets my needs, that is for sure.

I added the following code to passanger:

ServerName sitename.com
ServerAlias www.sitename.com
DocumentRoot /var/rails/sitename/public



Since i have two other sites on my slice, i need to make sure that the NameVirtualHost *.80 is only added to the "first" site or in other words, only once.

The best passanger, slice from scratch tutorial is Part One and Two of sys admin chronicles.

Change your DNS records on your slice and with your Registrar


You'll need to change where your DNS is pointed, i.e., from the OLD server to the NEW one. Slicehost makes that part easy with their DNS manager. For the registrar part, you need to go to the registrar of record, in order to point it to the new settings. I change the registrar's record first, then i change mine on slicehost. But again, that's what i've done.


Restart the App and you are done


I think that is it friends. You should have the same app as you had before working on a new server. This wasn't rocket-science but it was a good list of 'things you need to do' when converting over to a new server.


To do...


I'll post how i got a multi-website postfix configuration going on my slice. I've yet to find an easy tutorial that works... but i'm looking. Thanks everyone. The good times are rolling again.

Wednesday, December 3, 2008

Theme Support plugin update for Rails 2.2- Part 2.

So i have tried my damnedest to make this work. I get an error as follows:

undefined method `compute_public_path' for #
So, for some reason in theme support i am getting this crazy error, where in Rails 2.0.2 i did not, and in another project, which was Rails 2.1.2 using the "old" theme support, i did not get either


Possible Solution (TBD)

It appears that the compute_public_path method is now a private method of the class AssetTag in the module ActionView::Helpers::AssetTagHelpers.

What I still need to figure out


How in the hell do i link this 'sub class' AssetTag to the Module line in the rhtml_helpers.rb file in theme_support? I've tried various configurations to no avail. Who out there is a plugin god and can help out?

Tuesday, December 2, 2008

Theme Support plugin update for Rails 2.2

Commentary: This plugin always has to be updated after every version of a rails upgrade? I don't know why that is however? Perhaps it's the most unluckiest of plugins? carma? something... but like a trooper, it keeps on licking and ticking.



If you are using theme support and have recently upgraded your app to 2.2, you'll need to fix this plugin before you get anywhere. luckily jystewart from github has patched the plugin to work with 2.2. from what i see it may even fix it for a while, so that finally we won't have to keep patching this thing.



URL: http://github.com/jystewart/theme_support/tree/master

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.