Имеет много через ассоциации с условиями - PullRequest
1 голос
/ 04 октября 2011

Я пытаюсь добавить условие ко многим через ассоциацию без удачи. Это ассоциация в моей модели видео:

has_many :voted_users, :through => :video_votes, :source => :user

Я хочу получить только voted_users, у которого video_votes есть value, равное 1 для этого видео. Как бы я это сделал?

Ответы [ 6 ]

1 голос
/ 04 октября 2011

Я бы сделал это в 2 этапа:

Сначала я бы определил соотношение has_many :through между моделями без каких-либо условий.

Во-вторых, я бы добавил «область видимости», которая определяет условие «где».

В частности, я бы сделал что-то вроде:

class User < ActiveRecord::Base
  has_many :video_votes
  has_many :votes, :through=>:video_votes
  def self.voted_users
    self.video_votes.voted
  end
end

class VideoVote
  def self.voted
    where("value = ?", 1)
  end
end

class Video
  has_many :video_votes
  has_many :users, :through=>:video_votes
end

Тогда вы могли бы получить пользователей, которые проголосовали, используя:

VideoVote.voted.collect(&:user).uniq

, которые, я полагаю, вернутмассив всех пользователей, которые проголосовали.Это не тот код, который вы бы использовали - это просто фрагменты кода, но идея та же.

1 голос
/ 04 октября 2011

Я бы предложил создать метод модели в классе модели видео. Что-то вроде:

def users_with_one_vote
  self.voted_users, :conditions => ['value = ?', 1]
end

Затем в контроллере используйте video.users_with_one_vote

Тогда тестирование будет проще.

Любой шанс, что вы можете изменить имя этого столбца со значения.Может дать некоторые вопросы (зарезервировано?).

0 голосов
/ 04 октября 2011

Пока мы подбрасываем идеи, как насчет использования расширений ассоциаций.

class VideoVote
  scope :upvotes, where(:value => 1)
end

class Video
  has_many :voted_users, :through => :video_votes, :source => :user do
    def upvoted
      scoped & VideoVote.upvotes
    end
  end
end

Тогда вам приятно делать вызовы без каких-либо аргументов И технически вы не добавили другой методВидеомодель (это по ассоциации, верно?)

@video.voted_users.upvoted
0 голосов
/ 04 октября 2011

Лучший способ сделать это, не вмешиваясь в отношения, - создать более сложный запрос.Отношения - не лучшая вещь для этой конкретной проблемы.Пожалуйста, поймите, что отношения - это скорее «способ определения данных», чем способ «определения правил бизнеса».

Логика бизнеса или правила бизнеса должны быть определены на более конкретном уровне.

MyВаша проблема заключается в том, чтобы создать метод поиска пользователей, которые проголосовали по вашему видео только один раз.что-то вроде:

class Video < ActiveRecord::Base

  def voted_once()
    User.joins(:video_votes).where("video_votes.value == 1 AND video_votes.video_id == ?", this.id)
  end

Rails во многом волшебен, но сложные запросы все еще должны выполняться в стиле «SQL».Не позволяйте иллюзорной объектно-ориентированной метафоре ослепить вас

0 голосов
/ 04 октября 2011

Я обнаружил, что определение этого метода в моей модели работает:

def upvoted_users
  self.voted_users.where("value = 1")
end

, а затем вызов @video.upvoted_users делает свое дело.

0 голосов
/ 04 октября 2011

Будет ли

has_many :voted_users, :through => :video_votes, :source => :user, :conditions => ['users.votes = ?', 1]

Трюк?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...