Ошибка Rails 3: объект не поддерживает #inspect при включении (левое внешнее соединение) - PullRequest
3 голосов
/ 28 апреля 2011

Я использую Rails 3.

У меня есть 3 модели:

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

И я пытаюсь создать следующую область в модели сделки:

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

Что я хочу, так это все сделки, кроме тех, которые помечены как «желаемые» данным пользователем в блоке.Но всякий раз, когда я делаю это, я получаю следующую ошибку:

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)
 =>  

Кроме того, размещение его в функции не работает.Любая идея, что это может быть?

Спасибо!

РЕДАКТИРОВАТЬ: Это миграция таблицы Wishes

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

1 Ответ

1 голос
/ 28 апреля 2011

См. Обновление ниже vv

Старый ответ

Вы не используете Deal атрибутов для выбора, поэтому попробуйте переместить код в Wish класс:

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

Пример использования и вывод:

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)"

Это правильный результат для вас?

PS:

В Deal вы можете оставить прокси-метод, например:

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 (подзапрос)

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

Пример использования и вывод:

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 (внешнее соединение рельса)

Класс сделки:

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

Использование:

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)" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...