Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 error: Object doesn't support #inspect on includes (left outer join)

I'm using Rails 3.

I have 3 models:

class Deal < ActiveRecord::Base
  has_many :wishes, :class_name => "Wish"
  has_many :wishers, :through => :wishes, :source => :user
end

class User < ActiveRecord::Base
  has_many :wishes, :class_name => "Wish", :conditions => { 'wishes.wished' => true }
  has_many :wished_deals, :through => :wishes, :source => :deal
end

class Wish < ActiveRecord::Base
  belongs_to :user
  belongs_to :deal
end

And i'm trying to create the following scope in the Deal model:

scope :not_wished_by_user, lambda { |user| includes(:wishes).where('wishes.wished' != true, 'wishes.user_id' => user) }

What i want is all the Deals, except those that are marked as 'wished' by the given user in the block. But whenever i do that includes, i get the following error:

ruby-1.9.2-head > u = User.all.first
ruby-1.9.2-head > Deal.not_wished_by_user(u)
(Object doesn't support #inspect)
 =>  

Also, placing it in a function doesn't work. Any idea what this could be?

Thanks!

EDIT: These are Wishes table migration

class CreateWish < ActiveRecord::Migration
  def self.up
    create_table :wishes do |t|
      t.integer :deal_id
      t.integer :user_id
      t.boolean :wished, :default => true
      t.boolean :collected, :default => false
      t.datetime :collected_date
      t.timestamps
    end

    add_index :wishes, [:deal_id, :user_id], :uniq => true
  end
end
like image 811
acadavid Avatar asked Mar 22 '26 07:03

acadavid


1 Answers

See Update below vv

Old answer

You are not using any Deal attributes for selects so try to move code into Wish class:

class Wish < ActiveRecord::Base
  belongs_to :user
  belongs_to :deal

  scope :'wished?', lambda{ |f| where('wished = ?', f) }

  scope :not_wished_by_user, lambda{|user| wished?(false).where('user_id = ?', user)}
end

Usage exmple and output:

ruby-1.9.2-p180 :023 > Wish.not_wished_by_user(User.first).to_sql
  => "SELECT \"wishes\".* FROM \"wishes\" WHERE (wished = 't') AND (user_id = 1)"

Is this correct result for you?

PS:

In the Deal you can leave proxy-method like:

class Deal < ActiveRecord::Base
  has_many :wishes, :class_name => "Wish"
  has_many :wishers, :through => :wishes, :source => :user

  def self.not_wished_by_user(user)
    Wish.not_wished_by_user(user)
  end
end

Update1 (subquery)

class Deal < ActiveRecord::Base
  has_many :wishes, :class_name => "Wish"
  has_many :wishers, :through => :wishes, :source => :user

  scope :deal_ids_not_wished_by_user, lambda { |user|
    joins(:wishes).where('wishes.user_id = ?', user).where('wishes.wished = ?', false).select('deals.id')
  }

  scope :wished_by_user, lambda { |user|
    where("id not in (#{Deal.deal_ids_not_wished_by_user(user).to_sql})")
  }
end

Usage example and output:

ruby-1.9.2-p180 :023 > Deal.wished_by_user(User.first).to_sql
  => "SELECT \"deals\".* FROM \"deals\" WHERE (id not in (SELECT deals.id FROM \"deals\" INNER JOIN \"wishes\" ON \"wishes\".\"deal_id\" = \"deals\".\"id\" WHERE (wishes.user_id = 1) AND (wishes.wished = 'f')))"

UPD2 (railish outer join)

Deal class:

class Deal < ActiveRecord::Base
  has_many :wishes, :class_name => "Wish"
  has_many :wishers, :through => :wishes, :source => :user

  scope :not_wished_excluded, lambda { |user|
    joins('LEFT OUTER JOIN wishes on wishes.deal_id = deals.id').
      where('wishes.user_id = ? OR wishes.user_id is null', user).
      where('wishes.wished = ? OR wishes.wished is null', true)
  }
end

Usage:

ruby-1.9.2-p180 :096 > Deal.not_wished_excluded(User.first).to_sql
 => "SELECT \"deals\".* FROM \"deals\" LEFT OUTER JOIN wishes on wishes.deal_id = deals.id WHERE (wishes.user_id = 1 OR wishes.user_id is null) AND (wishes.wished = 't' OR wishes.wished is null)" 
like image 154
Viacheslav Molokov Avatar answered Mar 25 '26 01:03

Viacheslav Molokov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!