How to set up the Substruct, the Ruby on Rails Shopping Cart
Posted by Jason Sun, 29 Oct 2006 21:17:00 GMT
Substruct is a ruby on rails based shopping, its actually the only open source rails based shopping cart solution out there that at the time of this writing is worth mentioning. I have worked with other shopping carts, mostly OsCommerce and Zend. Although these other carts offer a bit more functionality having been around a lot longer, they seem to be stuck more in the web 1.0 paradigm and lack a lot of the modern eye candy that the next generation of websites demands. Substruct is rails based, so it is easy to hack on if you know a bit about ruby, and because of the rapid development being done in the rails community, there are always new plugins and engines that you could easily integrate much easier than PHP or Java based shopping carts. Some of the features available in Substruct are:
- A simple but effective CMS solution with blogging capabilities allowing you to manage your site's content via the web without any programming or HTML skills.
- The shopping cart itself allows you to connect to Authorize.net and allows real time shipping rate calculations from FedEx. Plans for Paypal and 2CheckOut payment processing modules are expected in the near future.
- Product and order management allowing you to track your inventory online with up to the minute sales reports. Also allows integration with fulfillment houses via XML and web services.
- An administrator interface that allows an admin to create and maintain content and orders, and facilitates collaboration between your store and your visitors.
- Its built with rails! Lots of web 2.0 customization options available.
The first thing I did was to create your rails application, the beginnings of your store. I built my cart on Gentoo Linux, however most of this in pretty distro independent as long as your on some flavor of unix. (I know nothing about building anything on Windows, so I don't know if its different or not..) Anyhow, create your application:
rails myapplication
After you see the scroll fly by and you are back to your prompt, change into the root of the application directory:
cd myapplication
Now, to make sure that everything is updated to the most current version of Substruct, we will use svn:externals. Inside the top level directory of your application, type:
svn pe svn:externals vendor
This will load a page in your favorite editor for you to adjust the properties. This will help keep you up to date by giving subversion a list of places to check for anything new. You should see something like this, if you are missing any of these lines just add them and write the file.
plugins http://svn.subimage.com/source/substruct/site/tags/rel_0.76Save this in the file and run "svn update" to see if you are in need. You should see the items being fetched from their externals. This is a convenient feature as you can update at any time by changing the external definition.
rails http://dev.rubyonrails.org/svn/rails/tags/rel_1-1-6
plugins/engines http://svn.rails-engines.org/engines/tags/rel_1.1.4
Ok, moving on. I am assuming that you know enough about rails to know what you need, such as a webserver of some sorts, a database, etc.. If this is a wrongful assumption, you should read up a little on rails first. The first thing we have to do is install the ruby gems that are dependencies of Substruct.
gem install payment
gem install shipping
gem install RedCloth
gem install RMagic
You need to include the Substruct application controller for your application to become aware of Substruct, to do this, make sure you have the following entry in myapplication/app/controllers/application.rb:
class ApplicationController < ActionController::Base
include SubstructApplicationController
end
You can delete application_helper.rb, has you don't need it. The documentation also recommends that you create a basic "loading.html" page but I'm not really sure why you need it.
rm myapplication/app/helpers/application_helper.rb
touch myapplication/public/loading.html
rm myapplication/public/index.html
Now we need to get some code. The best way to get it is to have subversion installed and get it from the subimage repositiory. I made a temp directory in my users home directory, changed into that directory and ran the following command to check out the source code. Inside of your temp directory, execute the following command:
svn co http://svn.subimage.com/source/substruct/site/trunk/vendor --username substruct --password substruct
You need to replace the vendor directory inside of your application root (myapplication) with the new vendor directory that you just checked out from svn. If you did as I did, you temp directory containing the checked out svn source is located in $home/temp/vendor, so make the swap. From in the document root:
cd myapplication
rm -rf vendor
cp -R $home/temp/vendor .
Then you can put the necessary configs in place, making sure that you either first delete the existing files, or verify that the copy overwrite the originals.
cp vendor/plugins/substruct/config_stubs/* config/
Take a peek at the shipping, payment and especially the GLOBAL variables in environment.rb, putting in the values that are appropriate for your application. There have also been reports of configuration values not being correctly recognized by gems, although everything seems to work fine on my system. If you notice that certain parameters are not correctly loading, you can set them in environment.rb so that they are called before the call to Engines.start. This would look something like:
module Substruct
config :some_option, "some_value"
end
According to typical rails convention, you should create three databases. One for development, testing and production. You really only need to create one, but it is best practice to create all three (you do test don't you?). Log into you database, and issue the following:
mysql> create database myapplication_development;
mysql> create database myapplication_production;
mysql> create database myapplication_test;
Set up your database.yml file to reflect your database user name and passwords, copy your schema's into place and then load them into the new databases:
cp myapplication/vendor/plugins/substruct/db/* db/
chmod +w db/schema.rb
rake db:schema:load
rake load_authority_data
rake db:migrate:engines:substruct
rake db:migrate:engines:substruct RAILS_ENV='production'
There are also default stylesheets provided with Substruct, as well as a useful javascript helper. It is easy to include these into your application layout by adding the following lines:
<%= engine_stylesheet "substruct" %>
<%= engine_javascript "substruct" %>
It wasn't perfect. My installation of Substruct did have some issues, which I did manage to overcome. Below is a collection of errors that I came across on the basic installation of Substruct that may help you if you happen to stumble across the same thing.
Substruct migration error:
When i try to run "rake db:migrate:engines:substruct" i get the following error:
eleven@peeps /var/www/localhost/htdocs/myapplication $ rake db:migrate:engines:substruct
(in /var/www/localhost/htdocs/myapplication)
Migrating engine substruct
== AddUserAndContact: migrating ===============================================
-- add_column(:questions, :email_address, :string, {:limit=>50})
-> 0.1845s
-- change_column(:questions, :answered_on, :datetime, {:null=>true})
rake aborted!
Mysql::Error: Invalid default value for 'answered_on': ALTER TABLE questions CHANGE answered_on answered_on datetime DEFAULT ''
(See full trace by running task with --trace)
I am not sure of the "correct" way to fix this. But, a work around to get you up and rolling is to open up the file myapplication/vendor/plugins/substruct/db/migrate/001_add_user_and_contact.rb and comment out these two lines:
change_column :questions, :answered_on, :datetime, :null => true
change_column :questions, :answered_on, :datetime, :null => false
You may have to clear out your databases (or if your not sure how to do that, just drop them and create them again) so that you don't get a follow up error saying that a column already exists. Then, with a clean database, repeat that step.
ImageMagick error:
I had this issue while installing Substruct on Debian stable, being used as a production server:
checking for Magick-config... no
checking for GraphicsMagick-config... no
configure: error: Can't install RMagick. Can't find Magick-config or
GraphicsMagick-config program.ImageMagick was installed on the server, but it could not find these required files. I found the solution to be:
sudo apt-get remove --purge librmagick-ruby-doc librmagick-ruby1.8
sudo apt-get install libmagick6-dev ruby1.8-dev
After than you can install the gem by:
sudo gem install rmagick
To check that RMagick is installed correctly, run the following command in your shell:
ruby -rrubygems -e "require 'RMagick'; puts Magick::Long_version;"
You should see something resembling the following output:
This is RMagick 1.14.1 ($Date: 2006/10/21 13:43:23 $) Copyright (C) 2006 by Timothy P. Hunter
Built with ImageMagick 6.2.4 09/11/06 Q16 http://www.imagemagick.org
Built for ruby 1.8.5 (2006-08-25) [i486-linux]
Web page: http://rmagick.rubyforge.org
Email: rmagick@rubyforge.org
This would tend to imply that everything is now correct with your RMagick setup. There where some errors along the way, if you are getting an error it may be one of the same errors that i got. If you found a new error and would like to post it at the bottom with how you fixed it, I'm sure others would be grateful..
Substruct Mongrel and Capistrano Error:
When I install RMagick and uploaded my application to server, under the Webrick server everything works great. However, when I installed Capistrano and Mongrel and tried to deploy with "rake deploy," Mongrel starts, but errors on following line of code:
require 'RMagick'
This is the error that proceeded:
NameError (uninitialized constant Enum):
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:123:in `const_missing'
/usr/local/lib/site_ruby/1.8/RMagick.rb:28
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
/app/controllers/channel_controller.rb:1
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:65:in `require_or_load'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:30:in `depend_on'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:85:in `require_dependency'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:98:in `const_missing'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:131:in `const_missing'
generated/routing/recognition.rb:21:in `recognize_path'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.3/lib/action_controller/routing.rb:510:in `recognize!'
/usr/lib/ruby/gems/1.8/gems/rails-1.1.4/lib/dispatcher.rb:38:in `dispatch'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/rails.rb:73:in `process'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:551:in `process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:550:in `process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:625:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:956:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:955:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:127:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/command.rb:199:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:235
/usr/bin/mongrel_rails:18The problem was that Mongrel does not have the environment variable LD_LIBRARY_PATH set correctly. If you put following code somewhere in your boot.rb file:
You get nothing. But under Webrick you get "LD_LIBRARY_PATH= /usr/local/lib". Know why? It turns out that the Mongrel process during Capistrano deployment is started by the sudo command. Sudo sanitizes environment variables passed from the parent process to its child process. Referencing the man page and some wise words from Anatol Pomozov you see that:
sudo tries to be safe when executing external commands. Variables that control how dynamic loading and binding is done can be used to subvert the program that sudo runs. To combat this the LD_, _RLD_, SHLIB_PATH (HP-UX only), and LIBPATH (AIX only) environment variables are removed from the environment passed on to all commands executed.
sudo sudo -V
You will see which variable are removed from the sudo context. So the LD_LIBRARY_PATH is not in the list of allowed variables, and RMagick could not find the shared libraries for RMagick (libMagick.so-VERSION and libWand.so-VERSION that should be located in /usr/local/lib) and that is why launching Mongrel failed. The solution that solved the problem and let Mongrel play nicely with RMagick is to add the library directory to /etc /ld.so.conf.
sudo su
echo /usr/local/lib>> /etc/ld.so.conf
ldconfig
This will add the directory to list of shared libraries and update the dynamic loader cache. Now, you hopefully you have a happy RMagick.
Substruct RMagick error on Gentoo:
Although Debian is a great production server, that or CentOS are what I live by for anything mission critical, I do love Gentoo on my workstation. I had a similar issue with the RMagick gem on Gentoo. It turns out that Gentoo has an rmagick ebuild in portage that works much better than the gem. If you are having an issue with getting a working RMagick setup on Gentoo, this is what worked for me. First, uninstall the RMagick gem:
gem uninstall rmagick
Then, emerge the rmagick ebuild from portage:
emerge -av rmagick
After you stop watching the source compile, things should work.
I will most likely be doing a lot more work building Substruct based applications, so I intend for this list of errors to grow.. Ill keep this article handy and update it with any future findings.. Have fun with Substruct / Debian / Gentoo / RMagick !
Composed by Jason K. Jackson
First, thanks for the write-up. Second, just to let everyone know, these instructions are a little out of date. Please follow the writeup here instead: http://dev.subimage.com/projects/substruct/wiki/InstallingSubstruct We are in the midst of working on an installer script, which hopefully should be done soon.