tag:blogger.com,1999:blog-71515956641323709462009-06-13T09:34:41.249-04:00Corey GrusdenCorey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.comBlogger57125tag:blogger.com,1999:blog-7151595664132370946.post-34827781100195568062009-04-13T11:42:00.003-04:002009-04-13T11:54:55.596-04:00REALLYFUCKINGIMPORTANTTitle get you? It got us.  Last week, my pair and I created a file while we were developing that was called "REALLYFUCKINGIMPORTANT".  Inside this file we wrote one line of what we needed to do *this* week.<div><br /></div><div>Usually, you leave yourself a broken test or two to figure out where you left off.  But we didn't do that.  Instead, this morning (Monday), we were wondering what the hell it was that we needed to remember and ran our app in staging and had an epiphany about a feature that we needed to write.  So we had a conversation about what we needed to do and how to go about doing it.</div><div><br /></div><div>After that we wanted to make sure our local working copy was up-to-date from our git repository.  We checked the current status by running, "git status"...</div><div><br /></div><div>To our surprise, we had a file named "REALLYFUCKINGIMPORTANT".  After viewing  golden line of wisdom in the file we laughed our asses off. </div><div><br /></div><div>Morale of the story: if you must, write to a file with a ridiculous name in your git repository if you don't want to write a broken test first.  Either works well.</div><div><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-3482778110019556806?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-47518347834303327652009-01-30T10:14:00.004-05:002009-01-30T11:11:13.970-05:00Introduce, Speak quickly, to the point, sit down.I gave my very first Pecha Kucha talk last night.  It was a blast. You get to work with only 20 slides and 20 seconds per slide.  <div><br /></div><div><div><span class="Apple-style-span" style="font-weight: bold;">Why give such a short presentation?</span></div><div>It's 6m 40seconds long.  It won't bore people to death for an hour if it sucks. Yes, your presentation probably bores the shit out of people if it's over 30min. Go fix it!  </div><div><br /></div><div>Also, it allows for more people to speak in a short amount of time so there's a lot of variety as far as presentation content goes for a group of people to watch instead a long presentation over 1 topic. </div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">20 slides?</span></div><div>Sounds easy, but it's not.</div><div><br /></div><div>At first you'll think that it's easy to fill 20 slides.  Then you start to realize 20 slides might be too much when you trim down your content.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">20 seconds per slide?</span></div><div>Sounds like a short amount of time, but it's not. It seems long while you practice, but then it's non-existant while you're actually giving the presentation. </div><div><br /></div><div>When you do your first run through after you have all your slides, you'll think to yourself that you need more content or words, but I can assure you -- you don't.  If you can picture in your mind that you're having a conversation that flows with the audience, you'll be alright.  Since there's not enough time for people to ask questions until the end, you can flow from slide to slide.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Topic?</span></div><div>You can talk about whatever you want.  To hit a greater crowd talk about something broad. The more specific you get, the less your crowd will understand. You pick. It's your 6min 40seconds of fame.</div><div><br /></div><div>Video of the Pecha Kucha night will be up as well as the slides from everyone's presentations at: <a href="http://www.refreshjacksonville.org/">http://www.refreshjacksonville.org/</a></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-4751834783430332765?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-83338378217477090682009-01-14T15:28:00.004-05:002009-01-15T09:44:12.834-05:00Another contender in the RubyOnRails CMS arenaI was asked to do a quick review of a new CMS called Ansuz. It's available on Github and is being developed currently. A few quick things for those interested in using it:<br /><br /><div>* It's under development as we speak, so there's a lack of documentation, almost non-existant</div><div><br />* If you're looking for something to get up and running ASAP, you might want to look at <a href="http://github.com/radiant/radiant/tree/master">RadiantCMS</a> <br /><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">How easy is it to install?</span></div><div>Somewhat easy.  It's not as easy as RadiantCMS, but the README on Github did a pretty good job in getting my install up and running in about 5-10min.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Everyone want's their own functionality.. so what about creating my own Plugin for Ansuz?<br /></span>Luckily, the Ansuz guy's wanted to lower the barrier of entry and used <a href="http://github.com/pivotal/desert/tree/master">Desert</a> by the <a href="http://www.pivotallabs.com/">Pivotal</a> guys to help with the plugin architecture.  </div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">How hard is it to implement the Plugin that I build?</span></div><div>The act of building a plugin is easier than other CMS's, but implementing it into Ansuz might be another problem.  Since I haven't given quite enough time to actually implementing one, I'll leave this to be discovered, soon.  </div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Does it have a cool interface like the other CMS packages out there?</span></div><div>No.  Ansuz's admin interface so far is very crude.  You can't knock it just yet, since it's still being developed.  So if you're a designer, help these guys out and jump in there!  The functionality of the admin interface doesn't seem too bad though.  Is it easy to understand? Sorta-kinda. It seems like there might be "too much" going on in the Admin interface, again, this could be dealt with after the majority of the CMS is done.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">How's the quality of the code-base if my company were to use it and build on it?<br /></span></div><div>Even though I would love for a company to use my open-sourced code, if it were still under development, I wouldn't feel right suggesting it to be used in production for a critical app just yet.</div><div><br /></div><div><br /></div><div>I'll continue my review and writing some documentation for Ansuz, so if you have any questions leave a comment and I'll see if I can't help you! </div><div><br /></div><div>--</div><div>update</div><div>--</div><div>Ansuz uses <a href="http://github.com/lazyatom/engines/tree/master">Engines</a> instead of Desert for their plugins.</div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-8333837821747709068?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com2tag:blogger.com,1999:blog-7151595664132370946.post-16481933776341074962008-10-24T16:22:00.012-04:002008-10-30T13:55:35.148-04:00FakeWeb; the most awesomest for stubbing HTTP contentOn my new open-source project <a href="http://www.twittercompare.com/">TwitterCompare</a> I wanted to have a better way of receiving JSON data in my tests when using <a href="http://github.com/jnunemaker/httparty/tree/master">HTTParty</a>.<br /><br />The following calling is to verify credentials against the Twitter API using HTTparty:<br /><br /><pre><span class="ident">get</span><span class="punct">('</span><span class="string">/account/verify_credentials.json</span><span class="punct">')</span><br /></pre><br /><br />The get() makes a call to Net::HTTP.request. However, I don't want to request data from Twitter in my tests since I'll be running them quite frequently and it's a waste of resources to contact their servers, wait a few seconds, receive some data, and then all my tests finish 5 seconds later as well as data that may change.<br /><br />The <a href="http://github.com/chrisk/fakeweb/tree">FakeWeb</a> fork by Chris Kampmeier is what I used and it is awesome. It will:<br /><ul><li>Intercept calls to Net::HTTP.request<br /></li><li>Check to see if the requested URL is one that needs to return test data</li><li>Returns test data</li></ul>The interception is automatic once you require the following libraries in your spec_helper.rb:<pre><span class="comment"># spec/spec_helper</span><br /><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">fake_web</span><span class="punct">'</span><br /><span class="ident">require</span> <span class="punct">'</span><span class="string">open-uri</span><span class="punct">'</span></pre><div><br /></div><div>To setup which URLs you want to be recognized and stubbed during your tests with FakeWeb do the following in your tests wherever you wish:</div><pre><span class="constant">FakeWeb</span><span class="punct">.</span><span class="ident">register_uri</span><span class="punct">('</span><span class="string">http://twitter.com:80/account/verify_credentials.json?</span><span class="punct">',</span> <span class="symbol">:response</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">/testfiles/http_responses/verifiy.response.json.txt</span><span class="punct">')</span><br /></pre>You can pass :response a string that is a path to a file to return that file or you can have it return a string.<div><br /></div><div>NOTICE: The port specification in the register_uri() call.  You need to include the port for the FakeWeb.registered_uri?(url) to return TRUE on an exact match.</div><div><br /></div><div>And that's it! </div><div><br /></div><div><br /></div><div><br /></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-1648193377634107496?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-87197841794644664462008-10-09T10:58:00.004-04:002008-10-09T11:17:04.283-04:00Deploying your Webby siteI've been using webby a lot lately.  It's hot for static-like sites.  The site that I've been really digging into Webby with is <a href="http://www.thedailyrefactoring.com/">TheDailyRefactoring.com</a>.<br /><div><br /></div><div>The cool thing about webby is it's capistrano-like deployment.  You can deploy your site after generating it by using the following command:</div><div><blockquote>$ webby deploy</blockquote>This won't work until after you setup some constants though.  In your "Sitefile" in the root of your webby-application, you need to set the user, host, and directory of where your site is going to be hosted.</div><div><br /></div><div># Sitefile</div><div>SITE.user = "web"</div><div>SITE.host = "<name_of_webserver>"</name_of_webserver></div><div>SITE.remote_dir = "/www/thedailyrefactoring.com"</div><div><br /></div><div>After that, you can deploy your site immediately! </div><div><br /></div><div>Word to the wise, it pays to setup public-key-authentication between your servers to make this process super simple.</div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-8719784179464466446?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-886653187014774832008-09-23T11:23:00.002-04:002008-09-23T11:39:19.906-04:00Blueprint CSS for the Non-designerI know that I'm not the only developer that sucks at graphic design.  When I'm hacking on a project or attempting to actually finish something useful I always use a CSS website template while doing it from somewhere like <a href="http://www.oswd.org/">Open-Source-Web-Design.org</a>.  I like things to look pretty. Even if it's in development.<div><br /></div><div>That's where Blueprint CSS comes into play.  I've used it on 2 little projects so far and it's marvelous.  It provides a very simple set of rules to follow to lay your site out in a grid-format, much like how a newspaper is laid out (for those of you that actually still read newspapers). </div><div><br /></div><div>The downside is, you still have to have a sense of style. </div><div><br /></div><div>Some links to help are: </div><div><br /></div><div></div><blockquote><div>Photoshop Tutorials: <a href="http://psdtuts.com/">http://psdtuts.com/</a></div><div></div></blockquote><div><blockquote>Get a feel for what good design is by Allan Branch's Flickr stream of good designs he comes across:<a href="http://flickr.com/photos/ispypurdydesigns"> http://flickr.com/photos/ispypurdydesigns</a></blockquote><a href="http://flickr.com/photos/ispypurdydesigns"></a></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-88665318701477483?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-75871670458961848372008-08-26T10:50:00.008-04:002008-08-26T23:15:56.561-04:00Damnit, I'm tired of testing!I lied!  I love it and it's totally helpful in the long-run.<div><br /><div><div>Bryan Liles came up with a cool acronym -- TATFT (test all the fucking time).  As soon as I heard him talk about this at ActsAsConference2008, he instantly made the best possible answer to testing.  It doesn't matter what framework you write your tests in as long as you write tests.</div><div><br /></div><div>Below are some quick guidelines for your tests to try to make it easier for those that are getting stuck as to "how to test" or "what should my tests contain for this type of test".  By no means are they the answer to all your problems, but somewhere that you can build off of:</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold;">Model tests:</span></div><div><ul><li>In rails, I would use rSpec or Test::Unit</li><li>STRONGLY suggest not to use instance variables<br /></li><li>If you start to write any code that interacts with an object other than your model, something is wrong with your model, don't try to fix it with shitty tests</li></ul><span class="Apple-style-span" style="font-weight: bold;">Controller tests:</span></div><div><ul><li>In rails, I would use rSpec</li><li>rSpec Storyrunner is nice, but *I* think it's a completely different realm for those that haven't been used to writing tests for very long</li><li>Try not to hit the database if you can</li><li>When dealing with tests that MUST hit the database or SOLR or Sphinx or (OLAP Cubes for those in a Enterprise-y environment) outside of the application code, categorize them somehow to separate them from the faster running tests so you can run them at night or every hour while running your main test suite in seconds</li></ul><div><span class="Apple-style-span" style="font-weight: bold;">View tests:</span></div><div><ul><li>I hate view tests</li><li>But I do them with rSpec</li></ul><div><br /></div></div></div></div></div><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-7587167045896184837?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-8587311869548965022008-08-12T11:10:00.003-04:002008-08-26T11:05:36.772-04:00association.is_working_properly?When working with a team on a project things can get quickly out of sync. However, when working with a geographically seperated team, things can get out of sync before it even happens -- quick. With source control and high level languages of today, being disorganized amongst team members is much better than it was a few years ago, but still still happens just as much.<br /><br />Things can go wrong while working on a team like this and usually do, quickly like I stated previously. One area they can go wrong is with migrations. This is where an issue can pop up when creating an association between your domain models.<br /><br /><blockquote>manufacturer = Manufacturer.new(:name => "Chevrolet")<br />manufacturer.models.build(:name => "Corvette")<br />manufacturer.models.build(:name => "S10")<br />manufacturer.save</blockquote><br /><br />In Rails, they're supposed to just work and most people can continue building their application without testing to make sure a "model" is associated (added to) a "manufacturer". The issue is if someone on your team blindly creates a migration and checks it in because they think they're a "guru" and don't need to test or run tests before checking-in. This is a <span style="font-weight:bold;">major-fail</span>. This problem happened in my current project and stopped development which pissed me off since my pair and I had to go back and fix someone else's mistakes when we should have been able to continue on with the features we needed to implement.<br /><br />When creating an associated domain model there's usually some sort of change that needs to happen to the database. This interaction or creation of, is created by a human -- you or me.  It's in the form of a migration as well.  The human element introduces a point of failure so it must be tested, even if it's something minor like adding a column that is used by the framework.<br /><br />The moral of this story is, test everything if a human has changed the state of it.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-858731186954896502?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-31643720706311004802008-07-10T13:31:00.004-04:002008-08-12T10:52:03.767-04:00PayPal Sandbox Username/Password errorDeveloping applications that utilize Paypal can be a bear. I've done it twice so far and for some odd reason Paypal likes to change things up frequently. <br /><br />After going through the 2,000 steps to signup for a developer <br /><br /><pre><br /><br />trunk/vendor/plugins/activemerchant-1.3.2/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb<br /><br /><br /> URLS = {<br /> :test => { :certificate => 'https://api.<span style="font-weight:bold;">beta-</span>sandbox.paypal.com/2.0/',<br /> :signature => 'https://api-3t.<span style="font-weight:bold;">beta-</span>sandbox.paypal.com/2.0/' },<br /> :live => { :certificate => 'https://api-aa.paypal.com/2.0/',<br /> :signature => 'https://api-3t.paypal.com/2.0/' }<br /> }<br /><br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-3164372070631100480?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-75111927508925787322008-07-09T16:28:00.003-04:002008-07-09T17:08:40.036-04:00GoalsGoals are a bitch. Over the years of doing research on being more productive or achieving what you really want, I've found goals to be a very powerful force. When a goal is defined in writing, it's tangible. That's why I believe so many people don't achieve what they want these days. Everyone is either too busy to write the goals down or they don't know how. I love examples and they really express what is being taught through application. So to help everyone out, here are some real goals that I made for myself when I first started consulting last year:<br /><br /><br />* Have 1 customer for atleast 3 months of work<br />* Atleast 10,000 in the business checking account for 1 quarter<br />* Not have to bill more than 30 hours a week<br /><br />That was it, those 3 goals. And 1 of them was severely underestimated while the other two I blew out of the water. You can guess. Had I not written these down, I would have had nothing to shoot for. Lately my life has been filled with other things I really want to do or obtain and those have been turned into goals as well. As of late, the goals that I had last year also included completing a Sprint and Olympic triathlon, which is what I did as well.<br /><br />The moral of the story is, write it down -- don't open Notepad or Things, use good ole fashioned paper and pencil and write them down on a little notecard and throw it in your sock drawer. I'm not going to tell you to look at it everyday, you'll look at it everyday just because your mind will drive you to look at it since they are things you want.<br /><br />By doing this, you'll accomplish what you want. You have to want to write them down first though.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-7511192750892578732?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-69636760775507471962008-05-28T15:13:00.003-04:002008-08-26T11:08:17.746-04:00Capistrano full-stack recipes now on GitHubAfter bitching and complaining, I've put my almost-complete-capistrano-tasks on GitHub to start maintaining. <br /><br />I created the tasks to help setup my VPS in as little time possible since I really don't want to be doing sysadmin stuff anymore. Been there, done that a few years ago. I'm done with it. So I created a few capistrano tasks that will take a bare-bones vanilla VPS and set it up to host rail(s) applications.<br /><br />Originally, I had nginx install and setup as part of it, but ended up deleting it at the last moment before putting it on GitHub. I don't want to deal with Nginx if I don't have to since I really love Apache -- especially with Passenger (mod_rails) now!<br /><br />So that's the first order of business is to add the http-server setup ASAP! Other than that, just some overall cleaning up will be done and documentation since the tasks were hacked out in as little time as possible to setup my server.<br /><br />Enjoy and please contribute ;) I'll be making it available as a gem ASAP too since it is usable in its current state, just not pretty -- yet.<br /><br /><a href="http://github.com/cgrusden/capistrano-server-assembly/tree/master">http://github.com/cgrusden/capistrano-server-assembly/tree/master</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-6963676077550747196?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-6869016980797678262008-05-28T14:42:00.004-04:002008-05-28T14:46:58.903-04:00Having an issue pushing to GitHub or other git repos?After going through all the correct setup steps to put your open-source project on RubyForge or GitHub you try to do a git-push and then receive errors when trying to git-push.<br /><br />So the question is, did you add your public key (if you created a new one for git'ing) to your authentication agent via ssh-add?<br /><br />$ ssh-add ~/.ssh/my_public_key<br /><br /><br />Done.<br /><br /><a href="http://csociety.ecn.purdue.edu/~sigos/projects/ssh/overview/ssh-add.html">ssh-add documentation here</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-686901698079767826?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-5969671914917658912008-05-27T17:34:00.004-04:002008-05-27T17:37:41.239-04:00Removing unwanted new files from your SVN working copySo you have a project in SVN. You create a few new files and decided you just want to delete them via the commandline real quick.<br /><br />projectroot$ svn st | grep '?' | awk '{print $2}' | xargs rm<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-596967191491765891?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-13767368443230810822008-05-21T10:05:00.004-04:002008-05-21T10:16:05.190-04:00mod_rails : RAILS_ENV funWhen hosting multiple Rails applications using the new mod_rails for Apache, all of the RAILS_ENV variables will default to 'production'.<br /><br />The way you can change what environment your Rails applications run in is by adding/modifying the following line in your httpd.conf:<br /><br /><span style="font-weight:bold;">RailsEnv staging</span><br /><br /><br />This is really the only inconvenience that I've found so far with mod_rails. Surely someone will allow for the <span style="font-style:italic;">RailsEnv</span> variable to be located inside a <span style="font-style:italic;">VirtualHost</span> block.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-1376736844323081082?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-32660327012081621572008-05-21T09:58:00.002-04:002008-05-21T10:05:12.511-04:00Apache+mod_rails(passenger)Wow, this is HOT. <br /> <br />I have been using a shared VPS for hosting my rails/PHP applications and using NGinx to do so. Yesterday I told myself I wanted a better solution if there was one. So on my VPS, I installed Apache and mod_rails (Passenger) in a matter of minutes and had all my sites back up with ease.<br /><br />I'm glad to be back on Apache, even though most of the configuration and performance tuning I've long become rusty on since alot of new features have come out for Apache.<br /><br />The fun will continue.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-3266032701208162157?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-87736519003106223702008-04-28T13:35:00.005-04:002008-04-28T13:52:18.977-04:00Generating Migrations just got easier for meI wanted to add a column "content" to the user's table. Most of us run the following to create a migration:<br /><br /><pre><span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">migration</span> <span class="ident">addContentToUsers</span><br /></pre><br /><br />That creates a migration with the following:<br /><br /><pre><span class="keyword">class </span><span class="class">AddContentToUsers</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span><br /> <span class="keyword">def </span><span class="method">self.up</span><br /> <span class="keyword">end</span><br /><br /> <span class="keyword">def </span><span class="method">self.down</span><br /> <span class="keyword">end</span><br /><span class="keyword">end</span></pre><br /><br /><br />What's generated is pretty green, so we'd have to add some add_column/remove_column statements like so:<br /><br /><pre><span class="keyword">class </span><span class="class">AddContentToUsers</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span><br /> <span class="keyword">def </span><span class="method">self.up</span><br /> <span class="ident">add_column</span> <span class="symbol">:users</span><span class="punct">,</span> <span class="symbol">:content</span><span class="punct">,</span> <span class="symbol">:text</span><br /> <span class="keyword">end</span><br /></pre><br /><br />Lots of not needed work. Why not just enter what we want onto the commandline when we run our migration? Enter the cool generator way of creating a simple migration:<br /><br /><pre><span class="ident">script</span><span class="punct">/</span><span class="ident">generate</span> <span class="ident">migration</span> <span class="constant">AddContentToUsers</span> <span class="ident">content</span><span class="symbol">:string</span><br /></pre><br /><br />This generates a sweet, simple migration like this:<br /><br /><pre><span class="keyword">class </span><span class="class">AddContentToUsers</span> <span class="punct"><</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Migration</span><br /> <span class="keyword">def </span><span class="method">self.up</span><br /> <span class="ident">add_column</span> <span class="symbol">:users</span><span class="punct">,</span> <span class="symbol">:content</span><span class="punct">,</span> <span class="symbol">:string</span><br /> <span class="keyword">end</span><br /><br /> <span class="keyword">def </span><span class="method">self.down</span><br /> <span class="ident">remove_column</span> <span class="symbol">:users</span><span class="punct">,</span> <span class="symbol">:content</span><br /> <span class="keyword">end</span><br /><span class="keyword">end</span><br /></pre><br /><br />Hot. Thanks for pointing this out <a href="http://blog.l4rk.com">l4rk</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-8773651900310622370?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-54917568652433915572008-04-14T19:13:00.001-04:002008-04-14T19:14:40.441-04:00Gem: eycapFor some odd reason, I had to put double-quotes around the URL for the source in the following for the EngineYard gem that helps with deployment<br /><br />gem install eycap --source "http://gems.engineyard.com"<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-5491756865243391557?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-66012108394762247962008-04-14T11:49:00.003-04:002008-04-14T11:55:35.563-04:00Plugin: ResourceControllerThe Mechnical Turk from <a href="http://www.ardes.com/">Argument from design</a> wrote this sweet ass plugin. It cleans up your controllers, removes redundancy -- hot!<br /><br /><br />http://svn.ardes.com/resources_controller/trunk/resources_controller/<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-6601210839476224796?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-32839966020968710922008-03-29T12:06:00.004-04:002008-04-15T18:27:58.695-04:00Jamit sucks. Yea, you heard me.Today I had an epiphany while looking at the codebase of a COTS (commercial off-the-shelf). Don't' get me wrong, I'm all for leveraging someone else's blood, sweat, and tear's for one-low-price. This time was different. It is the shittiest code I've everseen in a product that was purchased.<br /><br />All over the place you see the following:<br /><br />Nastiness #1:<br />//TODO: clean this up<br /><br />Nastiness #2:<br />//$siteHeader = mysql_connect()<br />$siteHeader = get_site_header();<br /><br />Nastiness #3 through infinity:<br />Code that is cryptic and forces duplication.<br /><br />This is from <a href="http://www.jamit.com/">JamitJobBoard</a>. <br /><br />Jamit, you suck. Plain and simple.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-3283996602096871092?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com1tag:blogger.com,1999:blog-7151595664132370946.post-60270805344205743492008-02-23T02:38:00.001-05:002008-02-23T02:38:53.092-05:00Give your capistrano script some EngineYard config loveI was attempting to deploy the latest changes to the server for the very first time on my machine and got a wonderful little message from capistrano telling me:<br /><br /><cite>`mongrel:restart' is only run for servers matching {:only=>{:mongrel=>true}, :roles=>:app}, but no servers matched</cite><br /><br />The fix? From what I understand is that you need to tell capistrano that your web and app roles are running mongrel like so:<br /><br /><pre>role :web, '42.69.187.666', :mongrel => true<br />role :app, '42.69.187.666', :mongrel => true</pre><br /><br />That should do it for you, should you have this issue.<br /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-6027080534420574349?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0tag:blogger.com,1999:blog-7151595664132370946.post-53876800206086465042008-02-14T01:36:00.004-05:002008-02-14T10:20:03.463-05:00RubyJax pairing funTonight's RubyJax meeting rocked out! Getting everyone to pair up and work on something interesting was exciting. I myself was able to work with Russ, really nice guy that wanted to learn more about Rails to kick his ColdFUSION habit!<br /><br />Also, thanks to the <a href="http://cs.jaxdug.com/">Jacksonville Developer's UserGroup</a> headed up by Jonathan Bates and crew. They sent out a reminder as well as their posting that helped bring in some new faces tonight, thanks guys!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-5387680020608646504?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com2tag:blogger.com,1999:blog-7151595664132370946.post-58771497731569916562008-02-14T01:16:00.009-05:002008-04-28T13:55:01.529-04:00specialized collections using has_manyHere's the following scenario:<br /><br />You have a ticketing system. You have a User that can create tickets. That same User can be assigned tickets. So how can you specify a <span style="font-style: italic;">has_many</span> for both cases for the User?<br /><br /><span style="font-weight: bold;">Table Schema:</span><br /><br /><pre><span class="constant">CREATE</span> <span class="constant">TABLE</span> <span class="constant">User</span><br /><span class="punct">(</span><br /> <span class="ident">id</span> <span class="constant">INT</span><span class="punct">,</span><br /> <span class="ident">title</span> <span class="constant">VARCHAR</span><span class="punct">(</span><span class="number">42</span><span class="punct">),</span><br /> <span class="ident">created_by</span> <span class="constant">INT</span><span class="punct">,</span><br /> <span class="ident">assigned_to</span> <span class="constant">INT</span><span class="punct">,</span><br /><span class="punct">)</span><br /></pre><br /><br /><br /><br /><span style="font-weight: bold;">The answer:</span><br /><br /><pre><span class="keyword">class </span><span class="class">User</span><br /><span class="ident">has_many</span> <span class="symbol">:assigned_tickets</span><span class="punct">,</span> <span class="symbol">:foreign_key</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">assigned_to</span><span class="punct">',</span> <span class="symbol">:class</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">Ticket</span><span class="punct">'</span><br /><span class="ident">has_many</span> <span class="symbol">:created_tickets</span><span class="punct">,</span> <span class="symbol">:foreign_key</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">created_by</span><span class="punct">',</span> <span class="symbol">:class</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">Ticket</span><span class="punct">'</span><br /><span class="keyword">end</span><br /></pre><br /> <br /><br /><span style="font-weight: bold;">In action:</span><br /><pre><span class="ident">u</span> <span class="punct">=</span> <span class="constant">User</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="symbol">:first</span><span class="punct">)</span><br /><br /><span class="ident">render</span> <span class="symbol">:partial</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">tickets/assigned_tickets</span><span class="punct">',</span> <span class="symbol">:collection</span> <span class="punct">=></span> <span class="ident">u</span><span class="punct">.</span><span class="ident">assigned_tickets</span><br /><span class="ident">render</span> <span class="symbol">:partial</span> <span class="punct">=></span> <span class="punct">'</span><span class="string">tickets/created_tickets</span><span class="punct">',</span> <span class="symbol">:collection</span> <span class="punct">=></span> <span class="ident">u</span><span class="punct">.</span><span class="ident">created_tickets</span><br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-5877149773156991656?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com1tag:blogger.com,1999:blog-7151595664132370946.post-70885283842471188742008-02-02T22:26:00.006-05:002008-02-13T00:53:21.370-05:00NGinx + PHP5 + MySQLHad a bitch ass time getting NGinx + PHP5 + MySQL working on Fedora 8. There's very little documentation and what little documentation there is, is in Russian.<br /><br />At anyrate -- Nginx is the webserver. It serves up content that's it. Because it does it's 1 job really well, that means you have to hook-in all the other shit that you want to use. In my case, I want to serve up PHP pages. Nginx isn't like Apache where you can compile PHP into. You have to host the PHP-FastCGI in a wrapper (lighttpd) that will be accessed by Nginx.<br /><br />When a request comes in for a .php file, nginx connects to the localhost usually on a port you specify to LightTPD. LightTPD is just sitting there twiddling it's thumbs waiting for shit like this to be requested. At that point, everything should work as planned -- your .php is served. See below for a list of steps that I think is close to being true.<br /><ul><li>user_connects_to_your_page </li><li>nginx sees request for .php page<br /></li><li>nginx contacts lightTpd and passes php page to be parsed </li><li>lightTpd passes page onto PHP-FastCGI being hosted </li><li>PHP-FastCGI handles .php page/request </li><li>page returned to nginx </li><li>user_is_happy<br /></li></ul>The install instructions below are Fedora 8 specific, so I'm sorry if you aren't running it. You should be able to follow the process flow regardless of your flavor.<br /><br />Install the following:<br /><ul><li>Nginx - the vanilla install will work</li><ul><li><span style="font-style: italic;">yum install nginx -y </span><br /></li></ul><li>Lighttpd - vanilla install will work yet again</li><ul style="font-style: italic;"><li>yum install lighttpd -y</li></ul><li>Php5 - here's the bitch.</li><ul><li><a href="http://www.php.net/get/php-5.2.5.tar.gz/from/a/mirror">download the source</a></li><li>untar it somewhere</li><li style="font-style: italic;">./configure --prefix=/opt/php --enable-fastcgi --with-mysql</li><li>(If you are running on the 64-bit version of Fedora you'll pull your hair out if you don't add the switch <span style="font-style: italic;">--with-libdir=lib64</span> at the end of the previous line)</li></ul><li>cross your fingers that everything got installed properly and will "Just-work" the first time<br /></li></ul><br />Now the fun starts. I'm not going to go into crazy detailed configurations, I'm just going to tell you which files you'll probably want to look at and some options since alot of that information is out there already. (do a <span style="font-style: italic;">find</span> for the files if they aren't in the same spot as mine)<br /><br /><ul><li>nginx.conf - this acts like apache's httpd.conf, pay attention to the server directories and port # in <span style="color: rgb(255, 0, 0);">red.</span></li><ul><li><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);">The port number, corresponds to the port that light-tpd is running on that you launch</span></span></li><li><span style="color: rgb(255, 0, 0);"><span style="color: rgb(0, 0, 0);">the directory is obviously the root of where all your php scripts will be running from</span></span><br /></li></ul></ul><span style="color: rgb(255, 0, 0);"></span><br /><pre><br /> server {<br /> listen 80;<br /> server_name myspace.com;<br /> access_log logs/myspace.access.log main;<br /> location / {<br /> root /sites/myspace.com;<br /> index index.html index.php;<br /> }<br /> location ~ \.php$ {<br /> fastcgi_param SCRIPT_FILENAME <span style="color: rgb(255, 0, 0);">/sites/myspace.com/</span>$fastcgi_script_name;<br /> fastcgi_param QUERY_STRING $query_string;<br /> fastcgi_param REQUEST_METHOD $request_method;<br /> fastcgi_param CONTENT_TYPE $content_type;<br /> fastcgi_param CONTENT_LENGTH $content_length;<br /> fastcgi_pass 127.0.0.1:<span style="color: rgb(255, 0, 0);">10004</span>;<br /> fastcgi_index index.php;<br /> }<br /> }<br /></pre><br /><ul><li>start-fastcgi.php - a script I made to just get the thing working</li></ul><pre><br />/usr/bin/spawn-fcgi -a 127.0.0.1 -p 10004 -u lighttpd -g lighttpd -f /opt/php/bin/php-cgi<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-7088528384247118874?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com3tag:blogger.com,1999:blog-7151595664132370946.post-40202043525132565402008-01-31T20:09:00.000-05:002008-02-10T23:36:28.544-05:00Vote NO on JoomlaA recent customer of mine had a small issue. His site was running on Linux utilizing Joomla. I realize how nice it is to use software right out of the box, but if the idea is to add ANY features, don't use Joomla. <br /><br />This specific customer wants some customization and it's going to be a royal pain in the ass to work with the code-base as it is. It makes me sick to my stomach having to work on a codebase that I know is not built for ease of maintenance or anything like that.<br /><br />One thing that stands out for an open-source project like this, is the amount of code that is commented out.<br /><br />Frameworks are nice to use, but you're better off trying to piece-meal together some other packages and build the application and THEN extract out what you like.<br /><br />PHP5 + Smarty Templates + phpAdoDB is your man, if he can't do it, you damn sure can't!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-4020204352513256540?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com1tag:blogger.com,1999:blog-7151595664132370946.post-39769987749863051372008-01-20T16:46:00.000-05:002008-01-20T16:50:35.727-05:00divergentCRMI just released an open-source project that I did in RubyOnRails. I had a project that I needed to do that starts out very similar to a basic CRM so I figured why not put out a basic CRM before I get into anything specific for the project I'm working on.<br /><br />It's very bare-bones. In fact, I'm sure I'll get a lot of "Whyd you do that" or "You suck", that's ok. Long as you follow it up with a "this is why". If not, then you should probably just put your laptop (or desktop) back in the box from the store you bought it from and take it back.<br /><br />The project is on RubyForget at: <a href="http://rubyforge.org/projects/divergentcrm/">http://rubyforge.org/projects/divergentcrm/</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7151595664132370946-3976998774986305137?l=blog.divergentsoftware.com'/></div>Corey Grusdenhttp://www.blogger.com/profile/11198538870568541615noreply@blogger.com0