Archive forICT

REST design with extra actions

Yesterday, I had to add some extra actions in my controllers, so I could view some charts. The problem was that Rails didn’t recognize the actions, becouse Rails sees you action name as an id.

But Rails wouldn’t be Rails if it didn’t had a clever solution. Lets say you have a a resource called “Resource” and a similar controller. You want to add a new action and view to the resource controller named “charts” .

Just open your routes.rb file and find the line where you map the resource and add the following:

1
  map.resources :resource, :collection => [:charts], :member => [:print_pdf]

For the sake of being complete, if have added a member. The diffrence between a collection and a member is that collections work on all items of that resource (no id needed, like index action),
so:

1
  charts_resources_path()

could be used and give you a page with covering the charts of all resources

while a member works on a single item of the resource, defined by it’s id

1
print_pdf_resource_path(1234)

would print the resource with id 1234 as pdf

of course like with all other REST actions (or CRUD actions, to be correct) you can use additional named params like:

1
2
chart_resources_path(:type => :monthly)
print_pdf_resource_path(1234, :font => "Arial")

Comments

Object-oriented approach to ActiveRecord

One of my colleges (the main programmer for the company I work for) has created a nice post on creating dynamic search criteria in an object-oriented way using Rails ActiveRecord. You can find his post here.

At first, I was a little out of balance, becouse I couldn’t realy see the advantage of it. But now after working on a few big rails projects, I realized quickly that this was a real neat way of generating a query in ActiveRecord.  Yet, I had to make a few changes.

First, create a class called record_finder.rb and add the following code:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class RecordFinder
 
  attr_reader :parameters
  attr_accessor :order_by 
 
  def initialize (bool_mode = 'AND')
    @bool_mode = bool_mode
    @sqls = []
    @parameters = []
    @includes = []
    @order_by = ''
  end
 
  def add (sql, *params)
    @sqls << sql
    @parameters += params
  end
 
  def add_ref(field, int)
    add "#{field.to_s} = ?", int
  end
 
  def add_wildcard(field, value)
    add "#{field.to_s} LIKE ?", "%#{value}%"
  end
 
  def add_range(field, range)
    if field.instance_of?(Hash)
      add "#{field['from']} >= ?", range['from']
      add "#{field['until']} <= ?", range['until']      
    else
      add "#{field} >= ?", range['from']
      add "#{field} <= ?", range['until']
    end      
  end
 
  def has_conditions?
    @sqls.filled?
  end
 
  def add_finder(finder)
    if finder.has_conditions?
      @sqls << finder.sql_string
      @parameters += finder.parameters
    end
  end
 
  def sql_string
    @sqls.collect{|sql| "(#{sql})"}.join(" #{@bool_mode} ")
  end
 
  def get
    if @sqls.length > 0
      [ sql_string ] + @parameters
    else
      nil
    end
  end
 
  def get_all
    options = {
      :include => @includes,
      :conditions => get,
    }
 
    if @order_by.filled?
       options[:order] = @order_by
    end
 
    return options
  end
 
  def include(path)
    unless @includes.include? path
      @includes << path
    end
  end
 
  def is_empty(var)
    return var == nil || var == ""
  end
end

The only special diffrence is the add_range action. With the add_range, you can search for a field in a sertain range. If the parameter is a Hash, you can use it to filter a record that has a start and end date. Otherwise, you just filter a range on one field.

The next step is to create a finder class that inherets from the RecordFinder class for all the resources you wish to search through. It might look like something as this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ResourceFinder < RecordFinder
  def by_user(user_id)
    add("user_id = ?", user_id)
  end
 
  def by_name(name)
    add_wildcard("name", name)
  end
 
  def read_search(search)
    if search
      self.by_name unless is_empty(search[:name])
    end
  end 
end

Now, you have 2 options on how to build your query. The first one is to call for all the actions needed in your controller like this:

1
2
3
4
5
  finder = ResourceFinder.new  
  finder.by_user(session[:user].id)
  finder.by_name(params[:search][:name])  
 
  @resource = Resource.find(:all, finder.get)

Now you build your search in your controller. But if you have a lot of search parameters, your index action could get ugly after a while. That’s why I have created the read_search action in my ResourceFinder.rb class. Just pass you search hash to it, and build your query in there. This way, you build-up is centered in the finder class and your controller stays neat and clean :)

Comments

Windows Update breakdown

Since I bought a new computer last weekend, I still had a few Windows Updates to download and install. But for some reason, none of them where able to install. After some googling I found out that the problem could be with my dll’s and that I had to re-register them in in registry.

So I had to create a bat file with the following content and run it:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Regsvr32 wups2.dll /s
Regsvr32 licdll.dll /s
Regsvr32 regwizc.dll /s
regsvr32 msxml.dll /s
regsvr32 msxml2.dll /s
regsvr32 msxml3.dll /s 
regsvr32 comcat.dll /s
regsvr32 shdoc401.dll /s
regsvr32 shdoc401.dll /i /s
regsvr32 asctrls.ocx /s
regsvr32 oleaut32.dll /s
regsvr32 shdocvw.dll /I /s
regsvr32 shdocvw.dll /s
regsvr32 browseui.dll /s
regsvr32 browseui.dll /I /s 
regsvr32 msrating.dll /s
regsvr32 mlang.dll /s
regsvr32 hlink.dll /s
regsvr32 mshtmled.dll /s
regsvr32 urlmon.dll /s
regsvr32 plugin.ocx /s
regsvr32 sendmail.dll /s
regsvr32 scrobj.dll /s
regsvr32 mmefxe.ocx /s
regsvr32 corpol.dll /s
regsvr32 jscript.dll /s
regsvr32 msxml.dll /s
regsvr32 imgutil.dll /s
regsvr32 thumbvw.dll /s
regsvr32 cryptext.dll /s
regsvr32 rsabase.dll /s
regsvr32 inseng.dll /s
regsvr32 iesetup.dll /i /s
regsvr32 cryptdlg.dll /s
regsvr32 actxprxy.dll /s
regsvr32 dispex.dll /s
regsvr32 occache.dll /s
regsvr32 occache.dll /i /s
regsvr32 iepeers.dll /s
regsvr32 urlmon.dll /i /s
regsvr32 cdfview.dll /s
regsvr32 webcheck.dll /s
regsvr32 mobsync.dll /s
regsvr32 pngfilt.dll /s
regsvr32 licmgr10.dll /s
regsvr32 icmfilter.dll /s
regsvr32 hhctrl.ocx /s
regsvr32 inetcfg.dll /s
regsvr32 tdc.ocx /s
regsvr32 MSR2C.DLL /s
regsvr32 msident.dll /s
regsvr32 msieftp.dll /s
regsvr32 xmsconf.ocx /s
regsvr32 ils.dll /s
regsvr32 msoeacct.dll /s
regsvr32 inetcomm.dll /s
regsvr32 msdxm.ocx /s
regsvr32 dxmasf.dll /s
regsvr32 l3codecx.ax /s
regsvr32 acelpdec.ax /s
regsvr32 mpg4ds32.ax /s
regsvr32 voxmsdec.ax /s
regsvr32 danim.dll /s
regsvr32 Daxctle.ocx /s
regsvr32 lmrt.dll /s
regsvr32 datime.dll /s
regsvr32 dxtrans.dll /s
regsvr32 dxtmsft.dll /s
regsvr32 WEBPOST.DLL /s
regsvr32 WPWIZDLL.DLL /s
regsvr32 POSTWPP.DLL /s
regsvr32 CRSWPP.DLL /s
regsvr32 FTPWPP.DLL /s
regsvr32 FPWPP.DLL /s
regsvr32 WUAPI.DLL /s
regsvr32 WUAUENG.DLL /s
regsvr32 ATL.DLL /s
regsvr32 WUCLTUI.DLL /s
regsvr32 WUPS.DLL /s
regsvr32 WUWEB.DLL /s
regsvr32 wshom.ocx /s
regsvr32 wshext.dll /s
regsvr32 vbscript.dll /s
regsvr32 scrrun.dll mstinit.exe /setup /s
regsvr32 msnsspc.dll /SspcCreateSspiReg /s
regsvr32 msapsspc.dll /SspcCreateSspiReg /s
exit

After running this script, I could install all the updates without any trouble.

Comments

Rails breadcrumbs

As I was working on my new project, I was in need of a some breadcrumbs to implement on my site. Since I hate doing the same task over and over again, I looked for a ready to deploy plugin. After some googling, I quicly realized that a standard way of creating breadcrumbs is virtualy impossible.

The way of creating your bread trail can depend on diffrent situations and can change from project to project. I just think that this way of generating your bread trail I realy neat, and would fit about 80% of most projects. The application controller code can even serve as a starting point for generating the trail dynamicaly.

Start and put the following in your application_controller.rb file:

 protected
   def add_breadcrumb name, url = ''
     @breadcrumbs ||= []
     url = eval(url) if url =~ /_path|_url/
     @breadcrumbs &lt;&lt; [name, url]
   end  
 
   def self.add_breadcrumb name, url, options = {}
     before_filter options do |controller|
       controller.send(:add_breadcrumb, name, url)
     end
   end

Theses methods will be used in other controllers to build up the trail. Offcourse, every trail starts with the Home page. So it would be stupid to repeat that in every controller. The author of the blog post suggested to put

add_breadcrumb 'Home', '/'

in the top of your application controller, but that gave some problems for me. So what I did is, since I use the initialize method in my application method, is just to put the code right there.

So how do you continue to build up the trail you might think now? Just open an arbitrary controller and add something similar to the top:

  add_breadcrumb 'Resource', '/resources'
  add_breadcrumb 'List', '', :only =&gt; [:index, :destroy]
  add_breadcrumb 'Create a new resource', '', :only =&gt; [:new, :create]
  add_breadcrumb 'Edit a resource', '', :only =&gt; [:edit, :update]

This way, all your crumb entries are grouped at the top of the controller. But if you need to customize, you can just add an entry in your action aswell.

Now, you would like to view your breadcrumbs. Go to the right view (most likely you default layout page) and add the following code:

<%= @breadcrumbs.map { |txt, path| "
  • #{link_to_unless(path.blank?, h(txt), path)}
  • " } %>

    Source: http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/

    Comments (2)

    Google Gears meets Ruby on Rails

    It has been a while since I posted something new. But I have a few articles in mind that I will post soon.

    The first one is something that I discovered a few days ago. The fantastic toolkit Google Gears that enables webapplications to work offline has met RoR.

    2 students, Michael Marcus and Rui Ma, have made it all possible. I haven’t had the time to play with it yet, but I’m working on a small project now that fits the need to experiment with.

    The things I can tell is that they wrote some sort of a wrapper that to work with all the javascript api’s that Gears has. Next to that wrapper, you still need some javascript to work within the browser, but the syntax looks very ruby-ish.

    Becouse crud-actions over http can be simulated, we can use the same views and controllers like we would use for a normal online application.

    The two students hope they can make it available as a plugin soon, so it can be used in existing projects.

    For more info, check out the Gears on Rails project page.

    Comments

    Firefox 3 out now!

    Jej, it is finally here. Firefox 3 is out. I was waiting a long time for this release. I dind’t use the beta or RC versions, so it was a bit hard to wait. But it was worth it. One of the main things I couldn’t wait for was the fact that FF 3 would consume less memory.

    Firefox 2 was consuming between 220.000 and 270.000k on my laptop. Now it only consumes between 40.000 and 70.000k. I haven’t take the time yet to test everything in detail.One thing I had problems with was Firebug. The 1.0.5 release doesn’t work under Firefox 3 and the getfirebug website is still down. But luckely I found a SVN build at MyZoneLabs that does the trick.

    So do not hesitate and GET FIREFOX 3.0 . Don’t forget, the Mozilla Foundation is trying to break the Guiness World Record of most downloaded software in one day. So if you stumble upon this post before 17:00 UTC on June 18, 2008 and downloaded Firefox, you are one of the many who is helping to acheeve this goal.

    Here is a changelog of FireFox 3.0

    More Secure

    • One-click site info: Click the site favicon in the location bar to see who owns the site and to check if your connection is protected from eavesdropping. Identity verification is prominently displayed and easier to understand. When a site uses Extended Validation (EV) SSL certificates, the site favicon button will turn green and show the name of the company you’re connected to. (Try it here!)
    • Malware Protection: malware protection warns users when they arrive at sites which are known to install viruses, spyware, trojans or other malware. (Try it here!)
    • New Web Forgery Protection page: the content of pages suspected as web forgeries is no longer shown. (Try it here!)
    • New SSL error pages: clearer and stricter error pages are used when Firefox encounters an invalid SSL certificate. (Try it here!)
    • Add-ons and Plugin version check: Firefox now automatically checks add-on and plugin versions and will disable older, insecure versions.
    • Secure add-on updates: to improve add-on update security, add-ons that provide updates in an insecure manner will be disabled.
    • Anti-virus integration: Firefox will inform anti-virus software when downloading executables.
    • Vista Parental Controls: Firefox now respects the Vista system-wide parental control setting for disabling file downloads.
    • Effective top-level domain (eTLD) service better restricts cookies and other restricted content to a single domain.
    • Better protection against cross-site JSON data leaks.

    Easier to Use

    • Easier password management: an information bar replaces the old password dialog so you can now save passwords after a successful login.
    • Simplified add-on installation: the add-ons whitelist has been removed making it possible to install extensions from third-party sites in fewer clicks.
    • New Download Manager: the revised download manager makes it much easier to locate downloaded files, and you can see and search on the name of the website where a file came from. Your active downloads and time remaining are always shown in the status bar as your files download.
    • Resumable downloading: users can now resume downloads after restarting the browser or resetting your network connection.
    • Full page zoom: from the View menu and via keyboard shortcuts, the new zooming feature lets you zoom in and out of entire pages, scaling the layout, text and images, or optionally only the text size. Your settings will be remembered whenever you return to the site.
    • Podcasts and Videocasts can be associated with your media playback tools.
    • Tab scrolling and quickmenu: tabs are easier to locate with the new tab scrolling and tab quickmenu.
    • Save what you were doing: Firefox will prompt users to save tabs on exit.
    • Optimized Open in Tabs behavior: opening a folder of bookmarks in tabs now appends the new tabs rather than overwriting.
    • Location and Search bar size can now be customized with a simple resizer item.
    • Text selection improvements: multiple text selections can be made with Ctrl/Cmd; double-click drag selects in “word-by-word” mode; triple-clicking selects a paragraph.
    • Find toolbar: the Find toolbar now opens with the current selection.
    • Plugin management: users can disable individual plugins in the Add-on Manager.
    • Integration with Windows: Firefox now has improved Windows icons, and uses native user interface widgets in the browser and in web forms.
    • Integration with the Mac: the new Firefox theme makes toolbars, icons, and other user interface elements look like a native OS X application. Firefox also uses OS X widgets and supports Growl for notifications of completed downloads and available updates. A combined back and forward control make it even easier to move between web pages.
    • Integration with Linux: Firefox’s default icons, buttons, and menu styles now use the native GTK theme.

    More Personal

    • Star button: quickly add bookmarks from the location bar with a single click; a second click lets you file and tag them.
    • Tags: associate keywords with your bookmarks to sort them by topic.
    • Location bar & auto-complete: type in all or part of the title, tag or address of a page to see a list of matches from your history and bookmarks; a new display makes it easier to scan through the matching results and find that page you’re looking for. Results are returned according to their frecency (a combination of frequency and recency of visits to that page) ensuring that you’re seeing the most relevant matches. An adaptive learning algorithm further tunes the results to your patterns!
    • Smart Bookmarks Folder: quickly access your recently bookmarked and tagged pages, as well as your more frequently visited pages with the new smart bookmarks folder on your bookmark toolbar.
    • Places Organizer: view, organize and search through all of your bookmarks, tags, and browsing history with multiple views and smart folders to store your frequent searches. Create and restore full backups whenever you want.
    • Web-based protocol handlers: web applications, such as your favorite webmail provider, can now be used instead of desktop applications for handling mailto: links from other sites. Similar support is available for other protocols (Web applications will have to first enable this by registering as handlers with Firefox).
    • Download & Install Add-ons: the Add-ons Manager (Tools > Add-ons) can now be used to download and install a Firefox customization from the thousands of Add-ons available from our community add-ons website. When you first open the Add-ons Manager, a list of recommended Add-ons is shown.
    • Easy to use Download Actions: a new Applications preferences pane provides a better UI for configuring handlers for various file types and protocol schemes.

    Improved Platform for Developers

    • New graphics and font handling: new graphics and text rendering architectures in Gecko 1.9 provides rendering improvements in CSS, SVG as well as improved display of fonts with ligatures and complex scripts.
    • Color management: (set gfx.color_management.enabled on in about:config and restart the browser to enable.) Firefox can now adjust images with embedded color profiles.
    • Offline support: enables web applications to provide offline functionality (website authors must add support for offline browsing to their site for this feature to be available to users).
    • A more complete overview of Firefox 3 for developers is available for website and add-on developers.

    Improved Performance

    • Speed: improvements to our JavaScript engine as well as profile guided optimizations have resulted in continued improvements in performance. Compared to Firefox 2, web applications like Google Mail and Zoho Office run twice as fast in Firefox 3, and the popular SunSpider test from Apple shows improvements over previous releases.
    • Memory usage: Several new technologies work together to reduce the amount of memory used by Firefox 3 over a web browsing session. Memory cycles are broken and collected by an automated cycle collector, a new memory allocator reduces fragmentation, hundreds of leaks have been fixed, and caching strategies have been tuned.
    • Reliability: A user’s bookmarks, history, cookies, and preferences are now stored in a transactionally secure database format which will prevent data loss even if their system crashes.

    Comments

    Rails new template file extensions

    For some of you that don’t know this yet (don’t be ashamed of yourself, I only heared about it a a few months back), Rails 2 recommends a new file extension for your template file.
    At this point, everyone was using template extensions like:

    • .rhtml
    • .rxml
    • .rjs

    To unify the template files, the Rails developers have come with a clever solution: chaning the template extensions so that they math up and tell you in what format they are.
    By doing this, your new template extensions should look like this:

    • .html.erb
    • .xml.erb
    • .js.rjs

    You are probably thinking: “everything looks alike now, except the rjs and haml templates. Why not using .js.erb?

    Well, the answer is quite simple.

    • .html.erb -> response format is in HTML,  parsed with ERB
    • .html.haml -> response format in HTML, parsed with HAML
    • .xml.erb -> response format in XML, parsed with ERB
    • .js.rjs -> response format in JavaScript, parsed with RJS

    If someone ever came up with a plugin that does the same Javascript actions for some templates. Those templates could be called .js.dudesplugin .

    You see now? It all makes sence. Rails is all about convention, so it wouldn’t make sense to make an exception from the naming scheme for RJS templates.

    Comments

    Rails and foreign keys

    There is one plugin that I use in all my projects, and that is the Foreign Key Migrations plugin from RedHill. Defining foreign keys can’t become easier then this. Since as far as I know, Rails migrations don’t set foreign keys in your database, so this is the best solution. It uses SQL-92 syntax and as such should be compatible with most databases that support foreign-key constraints.

    You can even use it for legacy column names that don’t end with “id”. There is even a generator for creating foreign keys on a database that currently has none, so you can easily start using it even at the end of a project.

    You can download the EDGE, 2.0 stable, 1.2 stable or 1.1.6 release, depending on your Rails version. Don’t forget the you need the RedHill on Rails Core .

    Comments

    Netbeans 6.1 Fast Debugger Bug

    Yesterday evening, I installed Netbeans 6.1 since I use Netbeans for my Ruby on Rails development. When developing today, I wanted to use the debugger, but for some reason I couldn’t seem to install the Fast Debugger again. After some research on the Netbeans site, I came accross the answer.

    Seems like there is a bug in Netbeans 6.1 that was discovered to late and ended up in the release. It will be fixed in a normal update, for the people that realy need the debugger (I guess every good developer), the fix is easy. Just uninstall the ruby-debug-base gem and install the fast-debugger-ide gem.

    Everything is working perfectly now :)

    Comments (2)

    RESTful programming… but what does it mean?

    I realy start to get into the Rails rabbit hole. The last 9 months or so, I’ve been working in some Rails projects for the company I work for during the day. I have learned a lot, but when reading other peoples blog, I still feel like a real Uber n00b. I started last weekend on a new project for Netronix . Since I wan’t this project to be like a future reference for other projects, I started to read a lot upon programming styles in RoR. One term that allways poped up was the REST. I saw it at the beginning when I just started to learn Ruby (and Rails) but never realy payed mutch attention to it. And it wasn’t mentioned even once in all of the Rails books that I read. So why bother.

    For some reason, I just wanted to know what REST was. So I started the quest at your friendly neighberhood search engine Google . And yes, you get a lot of good hits, but also a lot of junk. During my quest of knowledge, I stumbled apon a nice PDF called RESTful Rails Development . Its not big, but it explains the whole theory in a playful way.

    I could realy advice this light bedtime reading to everyone who has started learning Rails, and is just eager to improve his/her Rails skills.

    So this weekend I’ll start on refactoring my project. Hopefully it will pay of soon :) . Maybe RESTful programming will become a second nature :)

    Comments (1)

    Next entries » · « Previous entries