Search code examples
ruby-on-railsgoogle-drive-apirailsappslearn-ruby-on-rails

Spreadsheet Connection section, won't create the spreadsheet


While working on Daniel Kehoe's Learn Ruby on Rails book, I got to the spreadsheet connection section. I followed the workaround for google drive and I get the message sent flash notice, but when I check Google Drive I am not seeing a created

  • Learn-Rails-Example

    spreadsheet. This is my models/contact.rb file.

    require 'google_drive_v0'
    class Contact
      include ActiveModel::Model
      attr_accessor :name, :string
      attr_accessor :email, :string
      attr_accessor :content, :string
    
      validates_presence_of :name
      validates_presence_of :email
      validates_presence_of :content
      validates_format_of :email, :with => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}\z/i
      validates_length_of :content, :maximum => 500
    
      def update_spreadsheet
        connection = GoogleDriveV0.login(Rails.application.secrets.email_provider_username, Rails.application.secrets.email_provider_password)
         ss = connection.spreadsheet_by_title('Learn-Rails-Example')
        if ss.nil?
          ss = connection.create_spreadsheet('Learn-Rails-Example')
        end
        ws = ss.worksheets[0]
        last_row = 1 + ws.num_rows
        ws[last_row, 1] = Time.new
        ws[last_row, 2] = self.name
        ws[last_row, 3] = self.email
        ws[last_row, 4] = self.content
        ws.save
      end
    
    end
    

Here is the contacts_controller.rb to show that the Message from 'Contacts' should be sent to my email.

    class ContactsController < ApplicationController

    def new
      @contact = Contact.new
    end

    def create
      @contact = Contact.new(secure_params)
      if @contact.valid?
        @contact.update_spreadsheet
        UserMailer.contact_email(@contact).deliver
        flash[:notice] = "Message sent from #{@contact.name}."
        redirect_to root_path
      else
        render :new
      end
    end

    private

    def secure_params
      params.require(:contact).permit(:name, :email, :content)
    end

  end

When I load the server and then try to submit the contact form i get

Authentication failed for : Response code 403 for post https://www.google.com/accounts/ClientLogin: Error=BadAuthentication

And then this in the terminal:

     WARNING: GoogleDriveV0.login is deprecated and will be removed in the next version. Use GoogleDriveV0.login_with_oauth instead. Completed 500 Internal Server Error in 153ms
google_drive (1.0.0) lib/google_drive_v0/session.rb:109:in `rescue in login'
google_drive (1.0.0) lib/google_drive_v0/session.rb:102:in `login'
google_drive (1.0.0) lib/google_drive_v0/session.rb:43:in `login'
google_drive (1.0.0) lib/google_drive_v0.rb:19:in `login'
...learn-rails/app/models/contact.rb:15:in `update_spreadsheet'
...learn-rails/app/controllers/contacts_controller.rb:10:in `create'

Solution

  • I had the same error and whilst the issue for me was that I was using POW to serve up my dev site the steps I took to realise this might assist you.

    1. As you did I hard coded the variables in the update_spreadsheet method and this worked - proving the method and google_drive gem were good.

    2. I then pulled up rails console and did puts Rails.application.secrets.email_provider_username which got me my email address and proved Rails could see my environment variables.

    3. Assuming you are on the Rails 4.2 version of the book and have added gem 'web-console', '~> 2.0' to your gem file when you try to post the form and get the error you should get a console prompt. Here I ran puts Rails.application.secrets.email_provider_username again but this time got nil as an answer which confused me at first.

    4. This lead me to realise I was serving up the site with POW (http://pow.cx - a really cool way to serve up your dev sites) which uses its own .powenv file and so had no access to my variables. I confirmed this by running rails server and connecting via localhost:3000 and I could post without issue.

    5. so adding variables to the .powenv (and removing the file from git by adding to .gitignore) then resolved the issue.

    Hopefully some of the troubleshooting steps above may help you as it did me and you can complete the tutorial.