You probably don’t need an OLAP

It's a "well known" that relational databases are bad at multi-column "slice and dice" calculations.  So when you have data that you'd like to represent as an aggregated trend, it's easy to reach for that OLAP.  Chances are, you don't need it.  Here's an example of something where you want a count of the number of comments from an author by day.

select DATE(created_at) as DateOnly, count(*) 
from comments 
where author_id = 877081418 
group by DateOnly
order by DateOnly

The trick here is the DATE() function provided by various database vendors.  This returns any datetime as simply a date that can be aggregated.  

To be honest, I looked into this way too late and didn't contest the OLAP architectural decision until it was late.  We ended up having the legacy of dragging a big fat OLAP with all its trappings of complicating our architecture.  If you end up with a complex architecture, there's probably a simpler way you're not seeing.  The simpler your setup, the easier it will be for you to hold it all in your head and understand it when things go wrong.  

The only OLAPs we've found to be available was the open source Mondrian and Microsoft's Analysis Services.  To be honest, I found both to be way harder to use than it should have been.  If someone else wants to write another OLAP that's simpler to use without a lot of luggage to blow those two out of the water, the time is nigh.
Advertisements

Scope in JavaScript is just from which door you entered

Put simply, we entered BigComputer via new, so this meant “the new object.” On the other hand, we entered the_question via deep_thought, so while we’re executing that method, this means “whatever deep_thought refers to”. this is not read from the scope chain as other variables are, but instead is reset on a context by context basis.

Javascript’s scoping has been one of most confusing things about it, just as Ruby’s metaclass and object model is the most confusing things about it. If you’re looking to expand the horizon of what you understand about programming languages, it’s worth it to figure out javascript scoping.

The paragraph gave a good way to think about it:  this changes based on the object that calls the method.  It only gets confusing when you start passing around functions and using callbacks, which is most of the power of functional programming.

As an example, here, I was using an anonymous function as a callback in the request() method.  But it doesn’t work!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* This sample uses jQuery */

/* This doesn't work.
*
* Here, notice the success callback uses the data variable, except when called,
* the anonymous function can't access the data variable, since it's defined within
* the scope of the anonymous object that's sent to the request() method.
*/
function someEvent(event) {
    var data = { 'update-success' : "result_list", 'update-failure' : "error_list" };

    return request({ url : this.href,
                     success : function(response_html) {
                         $("#" + data['update-success']).html(response_html);
                     }
                   });
};

/* This works.
*
* Here, we've moved the success callback out of the context of the anonymous object
* and set it as the context of the someEvent() function. Thus, it will be able
* to access the data variable.
*/
function someEvent(event) {
    var data = { 'update-success' : "result_list", 'update-failure' : "error_list" };

    var success_callback = function(response_html) {
        $("#" + data['update-success']).html(response_html);
    };
    
    return request({ url : this.href,
                     success : success_callback
                   });
};

So that’s just one way to solve it.  If you’re using Prototype, you can also try using the bind() method.  jQuery doesn’t have an equivalent bind method, as hard as I looked for it at one time.  I was just about to write it myself (as it’s not too hard), but according to the a list apart article on Getting out of binding situations in javascript:

jQuery does not provide such a binding facility. The library’s philosophy favors closures over binding and forces users to jump through hoops (that is, manually combine lexical closures and apply or call, much as other libraries do internally) when they actually need to pass along a piece of code referring to “instance members.”

So while I use closures extensively in Ruby, I haven’t had to explicitly think about the scope until I was using closures in Javascript.  Huzzah.  Hopefully, it’ll prompt you to take a deeper look at Javascript.

Concurrency and integrity with validates_uniqueness_of

Here’s another tidbit that I hadn’t noticed in the rails docs before.  I was looking at validations for uniqueness and I saw this:

Using this validation method in conjunction with ActiveRecord::Base#save does not guarantee the absence of duplicate record insertions, because uniqueness checks on the application level are inherently prone to race conditions.

And the docs also offer some solutions:

This could even happen if you use transactions with the ‘serializable’ isolation level. There are several ways to get around this problem:  

 

By locking the database table before validating, and unlocking it after saving. However, table locking is very expensive, and thus not recommended.   

 

By locking a lock file before validating, and unlocking it after saving. This does not work if you‘ve scaled your Rails application across multiple web servers (because they cannot share lock files, or cannot do that efficiently), and thus not recommended. 

 

Creating a unique index on the field, by using ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the rare case that a race condition occurs, the database will guarantee the field‘s uniqueness.

This typically isn’t something you’d need to worry about until you get to some traffic of scale and size.  So don’t worry about it too much until you get there, but be aware of the problem.  Read the docs for more details and information.  tip! 

Amazon S3 and Paperclip plugin

Even after reading all the documentation, paperclip still has its quirks.  I've been pretty busy, but here's a short tip to tide you over.  When using paperclip with S3, make sure that you have the :path option set when using has_attached_file.  

It didn't take too long to figure out, but just in case, make sure bucket option is set either in the has_attached_file declaration or your s3 config file pointed to by :s3_credentials option.  Otherwise, you'll get a mysterious 

MethodNotAllowed: The specified method is not allowed against this resource.” Error.

So head on over to Scott Mottes and learn it step by step.  tip.