Tuesday, December 16, 2014

Rails force_ssl causing NginX infinite loop

Today I was configuring some new security features on one of my employers websites. One of them was feature to always force ssl on application.
In Rails 3.2.x and 4.x you can do that by just using force_ssl in Controller or in config/enviroment/production.rbMore info
Everything worked nice then I deployed to Staging and my server neded up in relally dumb infinite loop:
# log/staging.log
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Cache read: http://www.staging-my-app.com/?
Turns out that NginX needs to pass X-Forwarded-Proto header so that Rails recognize that "yes I'm on ssl"
# /etc/nginx/nginx.conf  # ..or one of your sites-enabled


  # ...
  location @unicorn {
    # ...
    proxy_set_header X-Forwarded-Proto https;
    # ...
    proxy_pass http://unicorn;
  }
source:

Friday, December 12, 2014

change Rack Test default host

If you're using Rack Test to test requests on your Sinatra application you will notice that by default the host isexample.org.
you can change this like this:
# spec/spec_helper.rb
def app
  MySinatraOrRackApp
end

module Rack
  module Test
    module Methods
      def build_rack_mock_session
        Rack::MockSession.new(app, 'api.myapp.com')
      end
    end
  end
end

# this has to be done before you do  `include Rack::Test::Methods`
note: Rack Test is the lib that is repsonsible for request test, so when you do post('/events')get('/', token: 123), ...

source:

Tuesday, November 11, 2014

Fetch Amazon s3 (aws) backup from console

If you are using backup gem for creating your backups to s3 bucket (or any other gem) logging to your AWS console web interface each time you want to download backup is painfull.
Much faster solution is to fetch the dump via console with s3cmd
sudo apt-get install s3cmd
First you need to create user http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html and add him a role that will allow s3 access (e.g. S3FullAccess )
Now that you have Access Key ID and Secret Access Key you can configure s3cmd
s3cmd --configure
One thing you should avoid are special chars in passphraze http://stackoverflow.com/questions/16512312/s3cmd-incomplete-format-error/16714176#16714176
To try if it works do:
s3cmd ls
You should see list of your bucket names. If you getting 403 you didn't configure your user role ore you misspeld the key/secret
Depending on where/how you store backups you can list what's the latest backup with:
s3cmd ls s3://my-project-production-dbbackup/production_db_backups/my-projcet_backup/
and download it with
s3cmd get s3://my-project-production-dbbackup/production_db_backups/my-projcet_backup/2014.11.11.10.07.14/my-project_backup.tar /tmp/

raw file: https://github.com/equivalent/scrapbook2/blob/master/archive/mini-blogs/2014-11-11-fetch-amazon-s3-backup-from-console.md

Thursday, October 23, 2014

Yielding Haml block will return 0 (zero)

I had a presenter-view code like this one:
class MyPresenter
  def render_content
    view_header = true
    yield(self, view_header)
  end

  def tlt(name)
    "fetching translation for #{name}"
  end
end
- language_presenter = MyPresenter.new
- language_presenter.render_content do |presenter, view_header|
  = content_tag :h2, presenter.tlt('top_header') if view_header
  = presenter.tlt('main_body')
  bla bla bla 
but for some reason the value of yield(self, view_header) was 0. Not nil, not empty string but a zero.
It turns out it was caused by the way how Haml outputs to the template. Long story short, using capture_haml will capture Haml to sting, and if you render that string with =  that will make it work properly:
- language_presenter = MyPresenter.new
= language_presenter.render_content do |presenter, view_header|
  - capture_haml do
    = content_tag :h2, presenter.tlt('top_header') if view_header
    = presenter.tlt('main_body')
    bla bla bla
source:


  

Wednesday, July 30, 2014

Rails deliver mail to local file


If you want to debug mail deliveries in development mode and want to see what exactly will be sent you can tell Rails to "deliver" emails to local folder file instead of sending them via sendmail or smtp.

# config/environments/development.rb
MyApp::Application.configure do
  # ...
  config.action_mailer.delivery_method = :file
  ActionMailer::Base.file_settings = { :location => Rails.root.join('tmp/mail') }
  # ...
end

In Rails 4.2 there is even better solution "Mail Previews" (... or show_previews) more info http://edgeguides.rubyonrails.org/4_2_release_notes.html#action-mailer
But still if you want ho have the raw mail output, this is still valid solution.
source:


keywords: Ruby on Rails 3, Rails 4, Rails 4.1, ActionMailer file

Thursday, May 15, 2014

Heroku app CNAME on Go Daddy


I'm Assuming:

  1.  you registered your domain at GoDaddy
  2. you have actual Heroku app that works on http://my_app.herokuapp.com
  3.  done everything correctly from https://devcenter.heroku.com/articles/custom-domains 
  4.  you have added your domain and www subdomain to heroku app like this:

$ ~/cd my_app
$ gem install heroku
$ heroku domains:add my_app.com
$ heroku domains:add www.my_app.com

now you want to point your GoDaddy  domain to your Heroku app with CNAME

1. login to goddady, and lunch your domain and click on "DNS Zone File" tab


2. Click "Add Record", Add CNAME, and point WWW to "my_app.heroku.com"


3. refering to http://support.godaddy.com/help/article/5289/updating-your-domain-names-ip-address-for-forwarding?locale=en&pc_split_value=3&countrysite=uk  you should point your A host  record  to  50.63.202.17

GoDaddy is changing design of their website too often, so if you cannot find these tabs, ...well, shit happens. Try to play around, they should be somewhere.

if you are looking for how to redirect / forward naked domain to www version directly from Go Daddy check this article: http://ruby-on-rails-eq8.blogspot.co.uk/2014/05/how-to-redirect-naked-domains-for.html




how to redirect naked domains for Heroku in Go Daddy

Assuming you already set your CNAME to point www on GoDaddy to your "http://my_app.herokuapp.com" (if not check this article: http://ruby-on-rails-eq8.blogspot.co.uk/2014/05/heroku-app-cname-on-go-daddy.html)

1. login to Go Daddy 

2. Lunch your domain

3. In Forwarding section click "Manage"


4. Redirect your naked domain to your "www.my_app.com" version  that is CNAME redirected to "my_app.herokuapp.com" (http redirect should be fine unless you want access to https version from naked domain;  use 301 so that Google will like you )




Friday, May 9, 2014

Make private method public in ruby




class Foo

  private

  def my_method
    'it work !'
  end
end
Foo.new.my_method
# => NoMethodError: private method `my_method' called for #<Foo:0x00000003ddb8e8>

Foo.send :public, :my_method
Foo.new.my_method
# => "it work !" 

class Bar < Foo
  public :my_method
end
Foo.new.my_method
# => NoMethodError: private method `my_method' called for #<Foo:0x00000003ddb8e8>

Bar.new.my_method
# => "it work !" 
source

Thursday, April 17, 2014

Rails console no database connection

Rails console no database connection

if this happens to you right after you load Rails 4 console:
rails c
User
 => User(no database connection)
It just means that ActiveRecord has not yet connected to the database and therefore does not know the column information. This is so that will not connect to DB unless needed to (speed improvements in Rails 4).
to connect just call
User.connection

# or

User.last
Rails 4