Rails Cache has unexpected side effects

Posted on Updated on

Unexpected
Unexpected

While working on a rails 4 site I noticed something strange. If I cache an ActiveRecord object and retrieve it twice the objects will have the same object id.

Here’s an example:

Advertisements

Bypassing ActiveRecord::DangerousAttributeError

Posted on Updated on

In Rails 4 if you try to access a Model with a column name that is a reserved word you are going to receive the error “ActiveRecord::DangerousAttributeError”

The most common solution I have seen is to use the ‘safe_attributes’ gem, unfortunately it has not been updated in 2 years, and I have read reports of people saying it is not compatible with Rails 4.

Here is the quick and dirty hack that I put together for PostgreSQL to bypass the error and allow active_record to access the column by a different name:

class MyModel < ActiveRecord::Base
    # Manually select all of the columns in the table
    default_scope{
        select('col1, col2, attribute as xattribute, col3, col4')}
end

# Reach inside of model
# and change the bad column name
MyModel.columns.find{|col|col.name=='attribute'}.
    instance_variable_set(:@name, 'xattribute')

Notice:

This code may make your hair fall out or kill your cat; coder discretion is advised.

Particularly, you should be aware that certain features of ActiveRecord may cause this configuration to throw an error. One example would be:


MyModel.all.count

ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR:

As long as you are aware of this, and you absolutely *must* be able to access the data, its not a huge price to pay.

Ruby Exception Classes Cheat Sheet

Posted on Updated on

I’ve seen several sites that describe the error classes that come in the standard library, but no where that gave a concise description on when to use them.

Rub Docs:

The built-in subclasses of Exception are:

  • NoMemoryError
  • ScriptErrorScriptError is the superclass for errors raised when a script can not be executed because of a LoadError, NotImplementedError or a SyntaxError. Note these type of ScriptErrors are not StandardError and will not be rescued unless it is specified explicitly (or its ancestor Exception).
    • LoadError: Raised when a file required (a Ruby script, extension library, …) fails to load.
    • NotImplementedError: Raised when a feature is not implemented on the current platform. For example, methods depending on the fsync or fork system calls may raise this exception if the underlying operating system or Ruby runtime does not support them.
    • SyntaxError: Raised when encountering Ruby code with an invalid syntax.
  • SignalException: Raised when a signal is received.
    • Interrupt: Raised with the interrupt signal is received, typically because the user pressed on Control-C (on most posix platforms). As such, it is a subclass of SignalException.
  • StandardError — default for rescue: The most standard error types are subclasses of StandardError. A rescue clause without an explicit Exception class will rescue all StandardErrors (and only those).
    • ArgumentError: Raised when the arguments are wrong and there isn’t a more specific exception
      • Ex: passing the wrong number of arguments
      • Ex: passing an argument that is not acceptable:
    • IndexError: Raised when the given index is invalid.
    • IOError: Raised when an IO operation fails.
      • EOFError: Raised by some IO operations when reaching the end of file. Many IO methods exist in two forms, one that returns nil when the end of file is reached, the other raises EOFError EOFErrorEOFError is a subclass of IOError.
    • LocalJumpError: Raised when Ruby can’t yield as requested.
    • NameError: Raised when a given name is invalid or undefined.
      • NoMethodError: Raised when a method is called on a receiver which doesn’t have it defined and also fails to respond with method_missing.
    • RangeError: Raised when a given numerical value is out of range.
      • FloatDomainError: Raised when attempting to convert special float values (in particular infinite orNaN) to numerical classes which don’t support them.
    • RegexpError: Raised when given an invalid regexp expression.
    • RuntimeError — default for raise: A generic error class raised when an invalid operation is attempted.
    • SecurityError: Raised when attempting a potential unsafe operation, typically when the $SAFE level is raised above 0
    • SystemCallError is the base class for all low-level platform-dependent errors.The errors available on the current platform are subclasses of SystemCallError and are defined in the Errno module.
    • SystemStackError: Raised in case of a stack overflow
    • ThreadError: Raised when an invalid operation is attempted on a thread.
    • TypeError: Raised when encountering an object that is not of the expected type
    • ZeroDivisionError: Raised when attempting to divide an integer by 0.
  • SystemExit: Raised by exit to initiate the termination of the script.
  • fatal – impossible to rescue

LimeSurvey on Ubuntu 14.04

Posted on Updated on

Recently I tried to run LimeSurvey on Ubuntu 14.04, but ran into cryptic errors. First I installed the dependencies: (with a postgres database)

sudo apt-get install apache2 php5 php5-pgsql php5-imap php5-gd php5-ldap

After everything was installed and ready to go I copied my limeSurvey files over to /var/www/html/surveys. When I went to http://localhost/surveys though LimeSurvey completely skipped the installation step and threw an error because the database did not exist. Feeling adventurous I manually created the database and grabbed some popcorn to see what would happen. It threw this error next:

The table "{{settings_global}}" for active record class "SettingGlobal" cannot be found in the database.

If I tried to run the Yii php console inside of LimeSurvey I ran into this error:

Uncaught exception 'CException' with message 'Application base path "protected" is not a valid directory.

The hint is right there, Application base path “protected”. It has something to do with either .htacces or FollowSymLinks. I need to figure out which one caused the issue at some point.

Long story short all of this was caused by something completely unrelated to LimeSurvey and the database. Ubuntu has changed the default Apache configuration. The solution that worked for me was to make sure that .htaccess files are enabled and FollowSymLinks is enabled in apache:

In /etc/apache2/sites-enabled/000-default.conf


    Options FollowSymLinks
    AllowOverride None


 
    Options FollowSymLinks MultiViews 
    AllowOverride All 
    Order allow,deny 
    allow from all 


It seems that the LimeSurvey Installation process will fail horribly, ideally it could throw an error message and give the user a hint at what is going on.

Gist

Posted on Updated on

Here’s a quick little app I wrote to back up our PostgreSQL databases.

https://gist.github.com/hattwj/11405978

Fun with port forwarding on Win7

Posted on Updated on

I tried for several hours to figure out the best way to enable port forwarding in Windows7. I normally use Linux, so I was admittedly a little out of my comfort zone, but you wouldn’t think that something simple like port forwarding would be a problem. It is. Most all of my google-fu returned results related to setting up port forwarding on a router (from a computer that just happens to be running windows 7). How is that even helpful?

Then I learned about the netsh.exe program. Ugg! I have no doubt that it is possible to set up a simple port forward with this tool, but an hour and a half later I hadn’t gotten it figured out. I’m not quite sure what the problem was, but I could not get it to forward the data to a different host.

Time to resort to open software. I installed Cygwin in windows and then installed socat. Socat is possibly related to the (in)famous netcat utility and really simplifies things.

#Cygwin forward connections in windows to our Linux VM
#send tcp connections at port 5500 to our vm on port 22
socat TCP-LISTEN:5500,fork TCP:my_nat_blocked_vm:22

# Create a reverse tunnel
# Connect to local machine and allow access to port 443
ssh -R 4499:localhost:443 user@my_local_address:5500

# Access restricted port on local machine
wget https://localhost:4499/

SSH append key to known_hosts

Posted on Updated on

A system I work on has rotating backup servers with different ssh host keys, so depending on the time of year etc… when I SSH in to the address I could be served with one of several servers. Essentially I need to have a single host with multiple key entries in my known_hosts file.
ssh-keyscan -t rsa example.com >> ~/.ssh/known_hosts