You are viewing a read-only archive of the Blogs.Harvard network. Learn more.

Debate

Okay… I got behind over the weekend. I skipped a couple of days and now I have to do double posts to keep up with my end goal.

But… I’ve also got to get to the gym. No really. I’ve got this wedding coming up and I think there’s a possibility that my ex-boyfriend who I haven’t seen in 15 years is showing up. Yeah.

After two kids it’s especially important to look sexy for this event… even though I think it might be a Star Treck/ Zombie theme.

Actually, I’m not sure if the groom is kidding about this or not. I’m hoping we do end up in costume. Although, honestly ladies trekkie costumes tend to be a little unforgiving.

Anyway, both endeavors are incredibly important. So I’ve really got to stay motivated. Thankfully, your feedback has been incredibly helpful. I’ve gotten some really great emails and comments from folks and I want to let you know that I really appreciate it.

Okay… gym now. Second post later. And if my dear friend does have a costumed wedding, I promise to bring mine to RailsConf!

August 16th, 2010

Give Me Something Slicker

In Episode 16: Virtual Attributes, Ryan shows us how to use virtual attributes to finess first and last name fields on a form. Of course, this is a very simplistic example. What about middle initials? Suffixes? Prefixes?

Every single time I try to use this feature, I find that usually there’s a very good reason these fields are separated in the database. Because mushing things together gets too complex when you start considering the edge cases.

Consider addresses or phone numbers. They’re straightforward enough until you start thinking globally.

I dunno. I’m sure there are brilliant examples out there of ways this can be used… but I’d like to see something a little slicker than just concatenating a name. got any examples to share?

August 16th, 2010

Find Me a Where Clause

I have always, always written out my find conditions the long way:

Post.find(:first, 
          :conditions => ['status = ? and active = ?', 1, 1])

And in some more complicated joins, this is entirely appropriate. But in Episode 15: Fun with Find Conditions, I’ve learned that you can specify conditions via a ruby hash:

Post.find(:first, 
          :conditions => { :status => 1, :active => 1 })

While the long way works just fine, what’s amazing to me is that this has been available since Rails 1.2. Where the hell have I been? Oh, yeah…. having two babies… but STILL!!

Fortunately,  Ryan’s got my back and I know (because I’ve been skipping ahead) that in Rails 3 the game changes and ActiveRecord provides a new interface for performing database queries.

Instead of :conditions we now use the where method, passing in the same arguments as we would to :conditions.

But whoa… let’s slow down there, Partner!  Baby steps.  Tortoise and the hare and all.

August 11th, 2010

Customizing Your Query

In the past, I avoided Performing Calculations on Models: episode 14 because I thought that under the hood rails was simply iterating through the array of active records returned from your sql query.

Turns out I was wrong.

There’s a much easier way than this to utilize the SQL functions and get the performance you want:

>> Task.find(:first,
             :select => 'SUM(priority)' 
             :conditions => 'complete=0')

In this episode, Ryan shows us the sql generated from his queries in the script/console and this:

>> Task.sum(:priority, 
            :conditions => 'complete=0')

creates the desirable sql query below:

          SELECT sum(priority) AS sum_priority 
          FROM tasks 
          WHERE (complete=0)

And of course this means that these methods are available through associations.  For example:

>> Project.find(:first).tasks.sum(:priority, 
                                  :conditions => 'complete=0')

is turned into this:

         SELECT sum(priority) AS sum_priority 
         FROM tasks 
         WHERE (tasks.project_id = 1) AND (complete=0)

What SQL functions are available?  Checkout the Calculations class in the api.

August 10th, 2010

Sessions are not caches

Is it just a coincidence that Episode 13 is fraught with danger?

In Dangers of Model in Session, Ryan devotes a whole episode to remind us not to store complex objects in our session.

Objects that are okay to store are very simple objects such as arrays, and strings, and ids, and hashes, and integers. But complex objects like models should be kept inside the database where the results are fetched every time.

There were a couple of comments on this post where folks noted performance problems as a reason to persist an object, but Ryan answers:

If you need a performance boost, look into a memcache solution.

But Ryan, I have to wait till episode #115!

August 9th, 2010

Refactoring

Since the weekend is upon us and the next few railscasts are a three parter, I’ve decided to combine episodes 10, 11 and 12 into this one blog post. I think that’s fair, don’t you?

Besides, I’m headed to the beach with my family on Sunday. And the ocean with two toddlers means all hands on deck!  It’s all about the kids, people… and the vodka… after they’re asleep in bed.

Ryan says:

Refactoring is improving the design of code without changing its functionality.

In episode 10, we can all agree that moving code from your view into the model is an obvious win.  And I appreciated watching Ryan show us in episode 11 the value of using an array to append a string over a local variable.  Really elegant.

It’s also nice to be reminded of .blank? which will return true if a string is either nil or empty.

But the most important takeaway is using testing to ensure that our zeal to refactor doesn’t break existing code.

Of course, we all test… don’t we?  Riiiiight?

In fact, I believe that the rockstars do.  But the rest of us folks are still doggedly trying to convince our boss of the ROI.

Perhaps your app is so big and so complex that you and/or your colleagues are afraid to refactor.  Well, this is when testing becomes invaluable.

Never tested before?  Don’t let that stop you.  Lord knows I was really intimidated before I wrote my first test.  And I know full well that I still have lots to learn.  But where do you start?

What’s the difference between a unit and functional test?  What about RSpec and Cucumber and all those tools and frameworks that make my head spin?

Let me be the first to virtually take hold of your hand and whisper, “It’s all gonna be okay.”

Just start with Unit Test.  It comes for free with every rails app.  Betcha you got a test directory in your app right now.  Sure, it’s a little neglected but maybe it just needs a little love.

I got a blog post that’ll walk you through the basics.  Chances are you’ve already seen the tutorials though and just need the confidence to get your feet wet.

Just pick a model and write a couple functional tests to start.  Betcha you get hooked.

August 7th, 2010

Security

O-M-G! Until episode #9: Filtering Sensitive Logs, I can’t believe that I’ve forgotten to worry about my log files. Which is pretty lame considering that I worked for StopBadware and discussed security issues on a daily basis.

Since SBW, I’ve been highly sensitive about encrypted passwords as well as browser and web host server software being up to date. Mostly because, it’s such an easy fix to thwart the casual hacker.

In fact, I get personally offended when I sign up for a web service and promptly receive an email displaying my registration info including my password in plaintext.

I mean, seriously people! Encrypted passwords are sooo last decade. We’ve moved on since then, haven’t we?

But holy obvious, Batman! Why did I forget to consider my logs files?!

Well, maybe because user authentication is done via popular gems these days like Clearance and Authlogic.

I just checked a side project I’ve been working on in which Authlogic is implemented and sure enough, filter_parameter_logging can be found in the Application Controller.

*Whew*!  Crisis avoided.

THIS is why it’s likely best to let others with oodles of security experience handle authentication and authorization.  Others will disagree, but I am very thankful that there are gems out there that let me concentrate on the other things that I’m good at and leave security management to the experts.

1 comment August 6th, 2010

Cleaner views with content_for

Episode #8 is all about content_for.  But isn’t content_for deprecated?  ….What?  ….Who said that?

Actually, what’s been deprecated is using an instance variable when accessing a content_for block. For example:

@content_for_#{name_of_the_content_block}

Don’t do that. Do it Ryan’s way.

In fact, the Rails API has some excellent documentation on content_for.

In passing, Ryan mentions that content_for can be used to create dynamic sidebars.  Err, the weblog of PJ Hyett and Chris Wanstrath go into much more detail in an old post Content for Whom?  Check it out. Good stuff.

Important to remember:

One caveat here is that content_for appends content. It don’t replace it.

Content_for is ignored in caches. So you shouldn’t use it for elements that will be fragment cached.

Since this railscast is an old one, I went looking around to see if this caching problem had been resolved somehow.  Best I could find was this solution from Idle Hacking. Hm.

I really, really like content_for. And I don’t think people use this enough. Instead I’ve been guilty of using if statements in my views… if this, render that, else render this… It can get pretty yucky.  But that caching bit has me concerned.

3 comments August 5th, 2010

Poly Wanna Headache

I’m skipping ahead today. Waaaay ahead. Because those railscasts are just so darn useful and I had a real work need to implement Polymorphic Associations. So, why not jump to episode 154? As if you could stop me. Ha!

Basically, my problem was this:

I have an existing rails app with model A and model B. But I needed a table that could hold either a pointer to one or the other.

You could make the most hardened database designers cry by creating a table containing both a model A id column as well as a model B id column. So instead, I chose to use a Polymorphic Association.

Now it wasn’t clear at first that this is what I needed. Originally, I was considering STI (Single Table Inheritance).

The archetypical example of STI is a cars table. While you might want to differentiate between a Ford and a Honda, they will typically have basically the same features. i.e. columns like horsepower, gas_mileage, price etc.

So with STI, you have one table that holds everything and in this example a parent model and two children models:

class Car < ActiveRecord::Base
end

class Ford < Car
end

class Toyota < Car
end

But there really isn’t much commonality between my two existing models. In fact, they are quite different and deserve tables of their own. So in my case, polymorphism is more appropriate. Thanks to @dpickett and this railscast for getting me started.

Sadly though, Ryan’s example is more RESTful than mine and my new feature can’t utilize nested resources… which means I couldn’t simply cut and paste the snazzy code he provided for the controller.

Instead, I need to work the other way ’round and grab all the objects in my new Model C.  Just for clarity, let’s keep Ryan’s comments example.  My index method looks something like this:

 def index
   @comments = Comments.find(:all, :order => 'commentable_type')
   @list = @comments.collect{|c| c.commentable_type == 'events' ?
                                 Event.find(c.commentable_id) :
                                 Photo.find(c.commentable_id) }
 end

It’s not horrible, but I wonder if there’s a better way. Thoughts?

August 4th, 2010

Layout-itis

Layouts are a great way of consolidating your header, snazzy css, site navigation and footer code. Creatives can rejoice since Ryan does a nice job of introducing all the different ways you can invoke layouts in episode 7: All About Layouts.

It’s nice to have the ability to utilize the appropriate layout strategy for different situations. Especially when dealing with the important admin and security features of your app which likely need to look and feel a little different than the rest of your app.

But sadly, I have seen examples of layout-itis in the wild leading to redundant css files and it’s… well, it can get really gross. Ugh.

But Ryan introduces a cleaner way of dealing with the worst of it… logic in your views. *Gasp!*  With a dynamic layout you can do the work in the controller.

For example, using dynamic layouts you can select a layout containing the appropriate navigation menus based upon user permissions in your controller.

But let’s take this a bit further.  You can instead have your application layout render a navigation partial based on user roles like this:

<%= render :partial => 'layouts/#{current_user.role.name}' %>
<%= yield %>

To make this *really* DRY, pass your menu items as a param to your partial.

After researching this a bit, it looks like lots of folks have already figured out sophisticated navigation techniques. A quick search revealed various gems and helpers already out there. What are your favorites?

So this is kind of getting out of the realm of layouts and into navigation and partials… but what I’m saying here is do yourself a favor and don’t get layout crazy. Likely, application layout is all you need.

August 3rd, 2010

Next Posts Previous Posts


Pages

Meta

Recent Posts