A grinch on rails

Notes from Ruby endeavors

RSpec controllers: testing if a method is used


it "does something" do
        controller.stub!(:any_conditional).and_return(true)
        controller.should_receive(:the_method).with("the arguement")
        get :index
      end
In the spec, the should_receive setup always goes before the request, in this case the get request. This essentially means that you are telling Rspec what it should expect to receive, and then request the controller and then test it. This may be confusing because in other spec you’d do the request and then run your “should ==” expectations, but it’s something to bear in mind.

Upload and download files in Sinatra

alfuken:

List

get '/' do
  list = Dir.glob("./files/*.*").map{|f| f.split('/').last}
  # render list here
end

Upload

post '/' do
  tempfile = params['file'][:tempfile]
  filename = params['file'][:filename]
  File.copy(tempfile.path, "./files/#{filename}")
  redirect '/'
end

Download

get '/download/:filename' do |filename|
  send_file "./files/#{filename}", :filename => filename, :type => 'Application/octet-stream'
end

Delete

get '/remove/:filename' do |filename|
  File.delete("./files/#{filename}")
  redirect '/'
end

Difference between ActiveRecord and an Active Model

ActiveRecord is an ORM to manage data in a relational database through SQL. It has automated mapping between classes and tables, attributes and columns. Associations between objects can be defined by simple class methods (such as has_many).

An Active model includes mixins and behaviours that make any Ruby object act like its corresponding ActiveRecord or ActiveResource by adding validations, callbacks, naming conventions, and so on. Models can also be connected to other models; this is done by defining associations.

Installing ruby version with Openssl

OpenSSL keeps giving segfaults (http.rb on line 799) so remove the current version from rvm then install it with:

rvm install ruby-1.9.3 —with-openssl-dir=/opt/local

Then CD to the project directory and override the rvmrc file by doing:

rvm —rvmrc —create use 1.9.3@project

To remove segfaults on http.rb:678 just move ‘pg’ gem to the bottom of the gemfile. How fucking strange is that? But it works.

Custom Devise authorization

If you use Devise and have a model, like Admin, which provides you with a free current_admin method, then you may want to provide segmented authorization for certain controller actions based on admin attributes. You can do this like so:

before_filter :check_for_admin, :only => [:new, :create, :edit, :destroy]

  private

  def check_for_admin
      unless current_admin.whatever["whatever"]
          redirect_to root_path, :notice => "Sorry, but you do not have permission for this action."
      end
  end

How to use before_filter to DRY up controller variables

If a variable is the same in several controller methods, take it out and added to a private method of its own name and make it accessible to all other methods using the before_filter.

class PagesController 
before_filter :list_stuff

def home
@title = 'Home'
end

def about
@title = 'About'
end

def contact
@title = 'Contact'
end

private

def list_stuff
@some_list = ['hi','bob','testy']
end

end

Deploying to Heroku

App made, now it’s time to deploy. It’s easy once both git and heroku as well as a new app (via `heroku create`) are setup on the system. CD to the app directory and do in order:
git add .
git commit -m "message goes here"
git push heroku master
Then it’s time to prepare the database so I run:
heroku run rake db:migrate
This actually gives me a strange error:
rake aborted!
bad URI(is not URI?):
However, running `heroku logs` reveals:
/Users/grinch/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/http.rb:644:in `initialize': getaddrinfo: nodename nor servname provided, or not known (SocketError)
Well, that’s pretty obvious, I haven’t added the Redistogo add-on in this application’s deployment. Let’s do that quick with:
heroku addons:add redistogo:nano
Done! Let’s test it up by firing up `heroku run console` and popping in:
REDIS.set("answer", 42)
It responds with “ok” - we’re in business. When trying to migrate the database again, it works great. I try accessing the app’s URL and it’s live!

Those pesky SSL certificate fail errors

When Ruby needs to communicate with external services (like the Facebook Graph API) you might get this error below:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
It’s because Ruby can’t find the certification authority certificates (CA Certs) to verify the connection to the service over SSL (and Facebook only allows HTTPS connections these days). A dirty fix is to download this file and stick it into your lib directory. Create a new file called
config/initializers/fix_ssl.rb
and add the following to it:

require 'open-uri'
require 'net/https'

module Net
  class HTTP
    alias_method :original_use_ssl=, :use_ssl=
    
    def use_ssl=(flag)
      self.ca_file = Rails.root.join('lib/ca-bundle.crt')
      self.verify_mode = OpenSSL::SSL::VERIFY_PEER
      self.original_use_ssl = flag
    end
  end
end

My solution, using Omniauth was just to reference to it in the Omniauth initializer:

Rails.application.config.middleware.use OmniAuth::Builder do  
   provider :facebook, 'xxx', 'yyy',
    { :scope => 'user_birthday, user_interests, user_activities, user_likes, user_location, offline_access',
      :client_options => {:ssl => {:ca_file => "#{Rails.root}/config/ca-bundle.crt" }}
     }
end