Home

Fix MissingTemplate Error in Rails

Recently, in my company project's Airbrake, found a lot of MissingTemplate errors, due to many requests didn't have "content-type", but a list of "http_accept", like, "text/*", actually we do have the "text/html", why it doesn't go to render it. Then I spend couple of days to look into Rails source code to find out the reason. In Rails, if you not explicitly write "render" method at the end of a Action, it will invoke a "default_render" method, which at action_controller/metal/implicit_render.rb, it first call "send_action" if after action method been executed still no "response_body", then it will run default_render. The render method is located at action_controller/metal/rendering.rb, although it has a method call chain, which super is at abstract_controller/rendering.rb. This render method will go to "AbstractRenderer#render", then finally "Template#render". but before the "Template#render", the Renderer will go to  "LookupContext#find_template" to find available template according to context. LookupContext#find_all, #find is the method find template, but it is using @view_paths.find_all, which is a ActionView::PathSet object. ActionView::PathSet#find_all, finally use FileSystemResolver#find_all to find file template. I looked into the code and debugged a little bit found the finally template finding behavior is Dir['"YOU_PROJECT/app/views/home/feedback{.en,.en,}{.json,}{.rhtml,.rjs,.builder,.rxml,.erb,}"'], it's actually is home/feedback{locale}{formats}{handler}, you can only change locale and formats by request header. So what's the  problem of MissingTemplate? because text/* wasn't been convert to text/json, text/html ... , but it is fixed in Rails edge. (4.0.0.beta)

#mime_negotiation.rb def parse_data_with_trailing_star(input) Mime::SET.select { |m| m =~ input } end

so Mime::Type.parse("text/*") will return correct result. Solution to solve this issue is:
  1. Let Mime::Type.parse */*, like Mime["text/*"] => text/html, text/json, text/xml
  2. Find exist template which match to the mime type list.
  3. If find the template, render it, or else, raise "MissingTemplate" error.
This is my solution for fixing it,  https://gist.github.com/1517007 This is the issue on rails github: https://github.com/rails/rails/issues/4127


present? and any? in ActiveRecord and ActiveModel

TIPS: Model.where().present? == Model.where().any? == Model.where().count > 0 Extension: Model.where().many? == Model.where().count > 1 Model.where().empty? == Model.where().count == 1 One thing different from #present? is Model.where().present? *!=* Model.present? Model.where().any? *==* Model.any? ree-1.8.7-2011.03 :029 > Benchmark.ms { PlannedRun.where("plan_id > 0").present? } => 606.235027313232 ree-1.8.7-2011.03 :030 > Benchmark.ms { PlannedRun.present? } => 0.0820159912109375 <--- Object.present? not ActiveModel#count > 0 SO My suggestion is: Using #any? at anywhere for active_record or active_model to check "any record exist?"

Theft-Alarm finally launched.

Recently I lost my old nokia phone then bought a new iphone 4, then I googled a little bit about anti-theft app of iphone, then I found a lot of people lost phone on bus or metro, when they are listening music..., when they realized they lost their iphone, the theft already gone. So theft-alarm will alarm just when thief unplug the headset(thief won't steal your headset, because it's stupid.). Vibration + Loud Alarm + Custom alarm sound will alarm at same time.   [gallery]

Manage authorized_keys on all of your servers.

SSH Key sync tool

This tool is used to mass deploy ssh-keys to all your servers according to the config. You can download at `https://github.com/hlxwell/ssh-key-sync-man`

Usage

  • gem install ssh-key-sync-man
  • Put all your team members' keys into one available_public_keys directory with the structure looks like:

    available_public_keys/groupA/michael

    available_public_keys/------/jason

    available_public_keys/------/john

    available_public_keys/groupB/rose

    available_public_keys/------/ryan

    • Add a server_list.yml, format like:
      servers: groupA: - host: xxx.com user: app groupB: - host: aaa.com user: app alias: app_server - host: aaa.com user: db alias: db_master (You can puts available_public_keys and server_list.yml at github, them people can add files by themselves)
      • ssh-key-sync-man -g groupA
        This will deploy public keys in available_public_keys/groupA to groupA servers

        "alias" list -- linux shotcut command list auto generator

        ssh-key-sync-man -a michael to generate alias for michael. Generate alias file for everyone, for example:

        michael alias myasics_app1="ssh app@host"

        alias myasics_app2="ssh app@host"

        alias myasics_db="ssh app@host"

        alias myasics_staging="ssh app@host"

        You can copy and paste into your .bashrc or .bash_profile