Sunday, October 9, 2016

Uninitialized constant error with Rails 5, Paperclip and Amazon S3

I haven't used Heroku to host anything in quite a while, but had a personal project that I wanted to put up and show someone. Unfortunately, every time you push an update to Heroku or the app reboots, it clears any files you've uploaded to it. I went ahead with setting up Amazon S3 for file storage and thought everything would be gravy to my dismay. Heroku gave me a 500 error when I tried uploading an image: NameError (uninitialized constant Paperclip::Storage::S3::AWS)
I wondered if it was an issue specific to Heroku, so I setup the Paperclip AWS config to test locally to no avail; I was still getting the same error. I immediately went to Google and tried all of the solutions I came across on Github and Stack Overflow to no avail; my problem persisted. I finally came across a post on Stack Overflow that had a similar error, and in the comments, someone suggested using the 5.0.0.beta2 version of the Paperclip gem. I updated my Gemfile to use that version: gem 'paperclip', '5.0.0.beta2' and after a bundle install - file uploads were working! I did have to specify the s3_host_name in my paperclip config to get images to display, but it worked. Since I haven't come across much information on this on the web, I thought I'd make a post about it. So if anyone else is having this issue, update your Gemfile to use a version of the Paperclip gem > 5.0. I updated mine to use Paperclip 5.1.0 and everything is working great.
gem 'paperclip', '5.1.0'
With the paperclip config as follows:
config.paperclip_defaults = {
    storage: :s3,
    s3_credentials: {
      bucket: ENV.fetch('S3_BUCKET_NAME'),
      access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
      secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
      s3_region: ENV.fetch('AWS_REGION'),
      s3_host_name: ENV.fetch('S3_HOST_NAME'),
    }
  }

Cheers.

Wednesday, October 5, 2016

Rails 5 resque error 'cannot load such file -- rack/showexceptions'

I decided to setup some background jobs for an app I've been working on, and decided to go with Resque for handling the jobs. I wanted to be able to run the resque jobs as rake tasks, so I added the appropriate lines to my Rakefile, but when starting my Rails server - I got an error:
! Unable to load application: LoadError: cannot load such file -- rack/showexceptions
After a little Googling, I came across this issue posted on the Sidekiq Github account. The recommendation was to add the Sinatra gem, which worked for Sidekiq users. I gave it a try, and that fixed the error for me as well:
gem 'sinatra', github: 'sinatra'
Just thought I'd throw this up in case anyone else came across this issue.

Cheers
 

Sunday, March 20, 2016

Apache subdomain virtualhosts over SSL

I've been scouring Google over the last couple of days, trying to find out how to setup subdomains over https without having to do IP-based virtualhosts or creating self-signed keys. It turns out the solution is pretty simple: set "NameVirtualHost *:443" (without quotes, of course) at the top of your SSL virtualhost config, and then you can proceed with setting up your virtualhosts as usual (I'm also redirecting all http traffic to https). For example:

Monday, November 9, 2015

How to retrieve and select all labels in Swift

I've recently started doing Swift development, and was tasked with finding a way to select each label that was swiped over in an app. I made multiple attempts at this, first trying a gesture recognizer, and then trying to implement code in the touchesBegan and touchesMoved methods to no avail. I could select a single label, but couldn't get multiple without implementing a gesture recognizer for each label (and that would be extremely repetitive, extraneous code). After a ton of Googling, I finally asked for help in the Swift subreddit, which got me REALLY close. The only thing I was missing was how to get a collection of each label in the app.
My first thought was to create an outlet for each label, and then create an array containing a reference to each label and using that, but that would again be time consuming, and just didn't seem efficient to me. I asked the author of the Reddit response what he was using in his code as an allLabels() function, but didn't get a response there, so I kept Googling. After a couple more days, I finally came across this beautiful Stack Overflow. They were getting an array of buttons, but I assumed that I could apply the same code to labels and voila! Problem solved, and it's SO simple. The code I ended up with for getting an array of all labels is as follows:
private var labels:[UILabel] = [UILabel]()
    
    override func viewWillAppear(animated: Bool) {
        for v:AnyObject in self.view.subviews {
            if v is UILabel {
                labels.append(v as! UILabel)
            }
        }
    }
Hope this helps anyone doing a similar search!

Thursday, March 19, 2015

minFraud Ruby gem

So I'm working on this new project that connects to the minFraud service, and there isn't a whole lot out there Ruby-wise for working with the API. The one gem that I did find is called minfraud-ruby. However, this gem seemed very limited. The minFraud service itself only requires you to send it an IP address, and a license key, but the gem also required city, state, zip and country. When you're working with IP addresses from countries outside of the US, some or all of these attributes will not be available. The gem also only returned a risk score. While the risk score is useful, there's much more useful data returned in the response from minFraud, such as ip_city, ip_region (which in the US is the state), ip_country_name, etc.
After working with the limitations for a while, I decided to fork the gem and give it a bit of an overhaul. I updated the required fields, so that now all you need is a license key and an IP address to get a response. Providing additional information will get you a more accurate response from the service, but this is not required. I also exposed a number of additional attributes in the transaction object, so you can retrieve things like city, state and country without any additional steps.

Happy coding, kids. Until next time..

Tuesday, July 9, 2013

Heroku fails precompiling assets with MySQL and Rails 4

I've been having a hell of a time deploying this app I'm working on to Heroku. For some reason, during the deployment process, while Heroku was precompiling assets, it would attempt to access the database at 127.0.0.1 and fail (obviously). I could precompile the assets locally, and deploy without a problem. At least, I thought it was without a problem. After implementing a WYSIWYG text editor into part of the app, the icons weren't showing up on the various buttons (for bold, italic, etc). So I decided to further investigate WHY my assets weren't precompiling on Heroku. I hopped in the Rails IRC channel, and a suggestion was proposed to try precompiling locally, with the environment set to production, but with a database that does not exist. Doing so should help to debug where the root of the cause was, and it did: Rails was failing on one of my validations. Enter: confusion. Why on earth is Rails attempting to run this validation whilst precompiling my assets? The validation in question is as follows:
validates :agree_to_contract, :acceptance => { :accept => true }, :on => :update, :if => :signer_full_name

agree_to_contract is a boolean, and signer_full_name is a string. I wanted the two fields to depend upon each other, and fail if one of them did not exist (there was a similar validation on signer_full_name for going in the other direction).
None of my initializers accessed the model which contained these validations, but yet - there was no way for me to remedy the issue. I attempted to wrap the validation in an ActiveSupport.on_load do end; still, the error persisted. This method seemed to be the culprit. It appeared as though the :acceptance block on the validation was causing the issue, but I was pretty much out of information to gather, so I headed over to the Rails issues tracker, to report a bug. After a bit of deliberation, and me producing some sample apps that displayed said behavior, it turned out that that this is, indeed, a bug. The cause is presently unknown, however, one of the contributors to the post hypothesized that the cause was eager_load! Hopefully the issue is resolved soon, and we can deploy checkboxes with validations to our heart's content ;)

Update:
A fix has been proposed, and it's working in my app! It's a pretty simple fix, too. edit config/environments/production.rb in your own app with the following:

replace config.eager_load = true with config.eager_load = true if config.eager_load.nil?

That's it. You should no longer have precompiling assets break with the :acceptance validation.

rails_admin with will_paginate undefined method `per'

So, I was going a bit crazy yesterday while working with the rails_admin gem. When I would click on my Users model, it would complain that I had an undefined method 'per'. Or, more specifically, the following:
NoMethodError (undefined method `per' for #<ActiveRecord::Relation::ActiveRecord_Relation_User:0x007fc945ba2b40>):
So, I did my usual rounds, searching Google and checking with the folks in the Rails IRC channel. It sounded like something related to pagination, but I hadn't touched anything that rails_admin would use related to pagination. I *had* added the will_paginate gem, so I tried commenting out the code I'd added to that, to no avail. Eventually, I got around to commenting out the will_paginate gem in my Gemfile, and voila! The error disappeared, and rails_admin worked as expected. Baffled, I added will_paginate to my search, and ran across this link. I added the work-around posted by @jackquack to config/initializers/will_paginate.rb:

(Note: Check updated code further down)
if defined?(WillPaginate)
  module WillPaginate
    module ActiveRecord
      module RelationMethods
        alias_method :per, :per_page
        alias_method :num_pages, :total_pages
        alias_method :total_count, :count
      end
    end
  end
end

I then uncommented the will_paginate code that I had commented out and cross my fingers. To my relief, upon booting up the server and going back in to rails_admin, everything was working!

So I decided to post about it in hopes of relieving someone else's /facedesk'ing :]

// Update 6/2017 I have just run into another issue a new issue with this solution:

! Unable to load application: NameError: undefined method `per_page' for module `WillPaginate::ActiveRecord::RelationMethods'

So the further solution that I have come across is to wrap the code in an ActiveSupport on_load block:
if defined?(WillPaginate)
  ActiveSupport.on_load :active_record do
    module WillPaginate
      module ActiveRecord
        module RelationMethods
          alias_method :per, :per_page
          alias_method :num_pages, :total_pages
        end
      end
    end
  end
end