RoR-e

If you haven't seen The 15 minute E-Commerce Site CLICK HERE


I'm currently looking for Contract jobs, Contact Me if you are interested. Dave.

ror_ecommerce Release Candidate David Henner Jan 16

Post a comment

This has been a long time coming. It's always difficult to decide when to cut the 1.0 release. You always want one or two more features. At the end of the day you there comes a time to say;

Its time for 1.0

Well that time has come. I made using the asset pipeline the last feature for the 1.0 release. My plan is to fix any minor bugs in the next few days, then cut the 1.0 in a couple weeks.

There are many plans for future versions of ror_ecommerce. Better navigation in the admin area is my primary goal. I feel this is the #1 priority. Two big changes will be added to address this.

  1. Add Twitter Bootstrap and remove blueprint
  2. Add rails_admin

These will be major upgrades for ror_ecommerce. In addition adding more sidebars for navigation will help current navigation.

I'm also hopeful to find more contributors, especially for the frontend. I'm not a big fan of adding too much css but at the end of the day people like to see pretty pages, even if they do plan to change everything later. :)

Lastly I'm hoping I can find some free servers for a demo. (sorry but I don't make and money from this project) This will allow me to add videos to show how to get ror_ecommerce up and running. It will also give people the ability to take a peek without doing any work.

If you are using ror_ecommerce ping me some of the URLs. My plan is to post some URLs on a sample page on ror__ecommerce. Also feel free to ask me questions if you are having issues.

Thanks, Dave

Asset Pipeline Best Practices David Henner Dec 15

2 comments Latest by DRH

When I first heard about the asset pipeline I got excited and a bit scared. Yes, I was scared because I love compass so much I assumed the community would be going in a direction that I didn't like. The good news, Compass works with the assets pipeline. Also Compass does many similar things to the asset pipeline that I can use some of my best practices from compass and continue using them with the asset pipeline.

The first thing I have been seeing in every example of the asset pipeline is the following line:

//= require_tree  .

This basically shows that you can include every css file (or js file) for your whole site. This might not be what you want. So the first thing I do in my application.css is write the following:

//= require_tree  ./application

Then I create a folder at app/assets/stylesheets/application/*

Now all my css files in this folder is for the entire application. Next I start creating several different files in this folder.

  • application/header.css.scss
  • application/footer.css.scss
  • application/app.css.scss
  • application/body_wrapper.css.scss
  • application/buttons.css.scss
  • application/sidebar.css.scss

What this starts to solve is the issue everyone has with css. Almost everyone creates an abnormally HUGE main.css file. Generally things get repeated and old css is never deleted because you aren't sure if it will affect something. UGH.

Having smaller files for specific parts of your layout prevents 5000 lines of code in one css file. It also gives you more confidence deleting old un-used css.

Next I like to namespace my css. This gives me 100% confidence that the css for the header will not affect the css for the footer. How do I namespace? Well you can do something like this:

#main-header {
  color:#FFF;

  .logo {
    border:1px #ACF solid;
  }

  h1 {
    font-size:40px;
  }
}

Do you see how ".logo" are "h1" are inside #main-header. This means these styles will only affect css inside the tag with the id='main-header'. Now I have 100% confidence if I change the h1 tag here it does not affect any other parts of the page.


Now it's time to battle javascript. (I'm not going to go into coffeescript.) I've always been good at properly namespacing my javascript. Here is a small example.

var MySite = window.MySite || {};

// If we already have the MyPage namespace don't override
if (typeof MySite.MySection == "undefined") {
    MySite.MySection = {};
}

// If we already have the MyPage object don't override
if (typeof MySite.MySection.mypage == "undefined") {

MySite.MySection.mypage = {
    initialize      : function( ) {
      jQuery('.test').live('click', function(){
        // do something
      });
    }
};

jQuery(function() {
  MySite.MySection.mypage.initialize();
});
}

Here MySite would be the namespace with the name of your URL (ex. Google or Yahoo). Unless your url is really long then you might want to abbreviate. Thus this namespace ensures you don't stomp on other site's injected JS.

MySection would be the namespace of your controller. Thus this namespace ensures you don't stomp your own JS.

mypage is the JS object you create for this page.

Unfortunately this section:

jQuery(function() {
  MySite.MySection.mypage.initialize();
});

Does not work well if you start including all your js files. You do not want to initialize this JS unless you need the JS. Yes you do want to include all your JS because the browser will cache the JS and sending one file rather than several files per page request is good.

So now the easy thing to do is add this small script to the view of the page that needs it. (please don't) Instead put this initializer in your page specific JS file. Then in your layout you would have something like this:

<body>
   <%= yield %>

   <%= javascript_include_tag "application" %>
   <%= yield :bottom %>
</body>

Next add the page specific javascript to it's own file. app/assets/javascripts/mypage.js

jQuery(function() {
  MySite.MySection.mypage.initialize();
});

Now in your page that you need the initializer script to run you do something like this:

<% content_for :bottom do -%>
  <%= javascript_include_tag 'mypage' %>
<% end %>

So now you actually send 2 *.js files. One for the entire app that will be most likely cached, the second will be a small file to initialize your specific JS for this page. Without worrying about the nasty global javascript most people have all over their site.

To be continued...

Stripe vs. ActiveMerchant David Henner Nov 14

7 comments Latest by Steven Sokulski

I've been playing around with stripe for the past month and I have been pretty impressed. It is so easy to use and the documentation is great. That being said there are downsides to stripe compared to ActiveMerchant.

  1. It does not support an authorize / capture workflow.
  2. You can only store one credit card per user.

When you first start using Stripe it appears the authorize / capture workflow will work just fine. If the customer enters their Credit Card every time, this is the case. What happens is stripe will give you a token for a charge amount. Then when you go to ship the item, you can do the capture of the payment.

Once you store the customer's Credit Card the authorize/capture workflow no longer works. Instead you charge the Credit Card at the time of the purchase. The upside is that you don't need to worry about expiration dates and possible double charges temporarily on the card. However if you find out the item purchased was never in stock you will have to return the money to the card. Additionally the "Stored Card" workflow is different than the "Manually Entered Card" workflow. I'm not a big fan of two separate workflows.

My issue also had to do with accounting. Double entry accounting methods are more accurate in an authorize / capture workflow. I won't go into the details but a lot of things needed to change in the app I used stripe.

Also only being allowed to store one Credit Card is a bit of an issue. In reality 95% of users will only store one Credit Card. If they need to change the card it is easy enough just by updating the customer's profile. I felt this was a minor enough of an issue that I didn't need to worry about it.

That being said Stripe has been amazingly easy to setup. The API is great and if you are dealing with a subscription based service stripe is a no-brainer. For a while I thought stripe was a Merchant/Gateway killer. I still believe gateways need to take notice because Stripe is a game changer. That being said, until they fully support auth/Capture there is a place for all the Gateways out there.

Now I just wish the banks could go away. =)

I'd love to hear feedback about ror_ecommerce moving to be 100% stripe over ActiveMerchant.

Thanks for reading.

Supporting Open Source David Henner Nov 02

8 comments Latest by Torsten

I remember when I was just a user of open source. I'd take all the gems and plugins and create some cool stuff. I'd work my butt off but never gave feedback to the creators of the open source world. I wish I had known how much feedback can help the whole community.

I remember having setup issues with several projects. I thought the maintainer must already know about the issue so what's the point in telling them. (BTW: creators of open source rarely setup the project)

It's amazing how wrong I was. Telling an open source maintainer about issues with their software can be the most important thing for a project. Everyone wins. In fact, every time someone has told me about an issue with ror_ecommerce I have personally fixed the bug in their software. Normally I get on a skype call and help them debug other issues.

I do this because I love creating the best software. It bothers me to find out someone has had an issue with an open source project but never bothered to send a message to the creator. Trust me you won't be hurting their feelings. Heck it gives me an adrenaline rush when i get negative feedback. Normally, I won't sleep until I at least have a patch ready.

How do we promote more feedback?

I don't have an answer. I have about 3 people giving me good feedback at any given time for rorecommerce. I know there are dozens of users that have gone to production with an rorecommerce site. When I find bugs that they must have confronted, I scratch my head. What can I do to endorse criticism? The critics are the people that make open source projects become great.

This week my plan is to quickly look through 3 open source projects. If I find something bad I'll inform the maintainer. On the other hand, If the gem "just works" I'll send a thank you message to the maintainer.

I'd love to hear comments about how other people have promoted feedback for their projects.

Budgeting a Project David Henner Oct 19

Post a comment

I was recently asked about how to budget a project and how to start the design phase of development by a non-tech guy. I thought the conversation was worth a blog post...

The first thing you should be doing is creating workflow diagrams with a tool like balsamiq. Most experienced developers will hesitate before giving you a quote because by nature business people need 100 to 500% more than they originally think they need. It's sorta the nature of software development. :)

That being said you should at the very least layout admin interfaces you need built up. I'd suggest going down to the detail of presenting the layout of every page.

For example:

Lets say we have an admin interface for creating users.

  • What does the interface look like for showing all users
  • edit user
  • show user
  • confirmation of changes to user
  • where do forms redirect
  • if I click on the user's name do I go to users page or admin user page.
  • should the sidebar on the show user look different than the show all users page

The workflows start to get very big very fast. That being said I would keep these workflows fairly rough. Change will happen 100% of the time once you start using the product.

Once you have the majority of the workflow diagrams done I'd personally ask a few developers how long it would take to build everything. Based off the average response triple time time. Your development costs are (hours * cost/hr). Tripling the time might feel crazy but trust me it is actually a conservative figure at the beginning of a project.

BTW, if you have 500 diagrams you might want to scale it down for your launch.

You will also have server costs and I would not take Quality Control for granted. I would also suggest not doing the quality control yourself. QA guys run through more scenarios than any business person would think of. (at least good QA people)

However, budgets are finite. I always suggest thinking about what your Minimum Viable Product(MVP) is and only make that. The example I always like is the hotdog stand. You don't need a bun or mustard. You don't even need a grill. Your MVP is a hotdog and a bucket of hot water. You will upgrade to get a grill and the bun later. :) Let's hope not too much later.

Once you have the cost your immediate idea will probably be, "I need a tech-cofounder". I suggest you read this article if you want a tech-cofounder. http://viniciusvacanti.com/2010/09/07/guide-to-finding-a-technical-co-founder/

Good Luck

Optimize early if it's easy David Henner Aug 27

7 comments Latest by Avdi

I constantly hear developers say don't optimize too early. I agree, to a point. This phrase became popular because you always see developers adding memcached to their project very early.

I believe developers will do this because it's fun. Also because developers don't think about opportunity costs the same way business guys think about it. At the end of the day if your site isn't in production yet then you need to focus on your minimal viable product(MVP). Your MVP most likely doesn't include memcached or any other cache strategy.

The problem comes when you take the phrase "don't optimize too early" to the extreme. It only takes 5 minutes to add indexes to speed up a majority of your searches. Adding them after the fact will lock your table and force your site to be offline for a longer period of time.

That was a no-brainer example but I've found creating generators that produce optimized code actually speeds up my application and my development time. A crazy consultant might argue you get to charge the client if you optimize in the future but I'd argue that consultant should be on an unemployment line. Companies pay you to do a good job, not a half-assed job.

I've also found that creating generators to do the work up front will save me time now and save me time from optimizing in the future. Here is an example generator that I use for controllers.

  def create
   @post = Post.new(params[:post])
   respond_to do |format|
     if @post.save
       format.html { redirect_to(post_url(@post), 
              :notice => 'Post was successfully created.') }
     else
       form_info
       format.html { render :action => "new" }
       format.json { render :json => @post.errors.to_json }
     end
   end
  end #end of create 
private
  def form_info
     # get information that populates form dropdown
     @states = State.select([:name, :id]).all.map{|s| [s.name,s.id]}
  end

Most rails developers will tell you to use a before filter to query for form information that populates your form drop-down menus. Sure that works... BUT you are making extra queries for successful create and update actions. You don't need those extra queries and taking them out when you start to scale is a lot of work and probably isn't worth your time at that point.

Attacking this strategy in a generator means you have no extra work up-front. I understand this might appear to be a small gain. If you scale this is a big win that causes no extra work while you are creating your application.


ror_ecommerce, ruby on rails ecommerce done right