Mladen Danic
Mladen Danic

Reputation: 3667

Rails active record object save action fails because of a malformed query

I have a problem in Rails in the part of my app that handles landing pages for registration emails. When a user is invited to the app, an Invitation active record instance is created, and user is sent an email with a link containing the id of the invitation (a random string token).

Then, when the link is clicked, I store that token in session, and at one point in the service layer, I update it's 'status' attribute to 'clicked', something like this:

    @invitation = Invitation.find_by_id(session[:registration][:invitation_token])

    unless @invitation.blank?
        session[:registration][:account_details]['referer'] = @invitation.promoter.username

        unless @invitation.status == APP_CONFIG['invitation_status']['clicked']
          @invitation.status = APP_CONFIG['invitation_status']['clicked']
          @invitation.save
        end
    end

Upon executing the @invitation.save line, I get an active record error:

!! #<ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'invitations.' in 'where clause': UPDATE `invitations` SET `status` = 'clicked', `updated_at` = '2015-11-11 11:07:24' WHERE `invitations`.`` = 'fd05ee5a-e790-48cc-9e7e-d30d3e88919b'>

The Invitation's id column name seems to be ommited from the query for some reason, and I can't figure out why. Not sure what is wrong or what to do.

Invitation migration:

class CreateInvitations < ActiveRecord::Migration
  def change
    create_table :invitations, id: false do |t|
      t.string :id, limit: 36, :auto_increment => false
      t.string :promoter_id
      t.string :email
      t.string :status

      t.timestamps
    end
  end
end

Invitation model:

class Invitation < ActiveRecord::Base
  #region Callbacks
  before_create :set_uid
  #endregion

  belongs_to :promoter, class_name: 'User', foreign_key: 'promoter_id'

  private
  def set_uid
    self.id = SecureRandom.uuid unless self.id
  end
end

Upvotes: 1

Views: 297

Answers (1)

chumakoff
chumakoff

Reputation: 7054

You should mark the id column as the primary_key:

create_table :invitations, id: false do |t|
  t.string :id, limit: 36, primary_key: true, auto_increment: false
  ...

I think that in your case the best way to solve this problem is to drop the table and create it again with correct migration. But if there is data that you don't want to loose, you can also try to do it like this:

class MarkIdAsPrimaryKey < ActiveRecord::Migration
  def change
     change_column :invitations, :id, :string, limit: 36, primary_key: true, auto_increment: false
  end
end

Keep in mind that this migration is not reversible, it remains under your responsibility if you will use it ) Good luck !

Upvotes: 1

Related Questions