rails has_many setter должен установить условия, если указано - PullRequest
3 голосов
/ 26 апреля 2011

Мне кажется, что это ошибка в Rails, но, вероятно, я мало что могу с этим поделать. Так, как я могу достигнуть моего ожидаемого поведения?

Предположим, у нас есть:

class User < ActiveRecord::Base
  has_many :awesome_friends, :class_name => "Friend", :conditions => {:awesome => true}
end

и выполнить код:

>> my_user.awesome_friends << Friend.new(:name=>'jim')

После этого, когда я проверяю этот объект друга, я вижу, что поле user_id заполнено. Но я также ожидал бы увидеть «удивительный» столбец, установленный в «true», но это не так.

Кроме того, если я выполню следующее с консоли:

>> my_user.awesome_friends << Friend.new(:name=>'jim')
>> my_user.awesome_friends
= [#<Friend id:1, name:"jim", awesome:nil>]
# Quit and restart the console
>> my_user.awesome_friends
= []

Есть мысли по этому поводу? Я полагаю, что хэш условий может быть произвольно сложным, что делает невозможной интеграцию в сеттер. Но в некотором смысле кажется, что по умолчанию мы передаем условие ": user_id => self.id", и это устанавливается, так что не должны ли другие?

Спасибо, Mike

EDIT:

Я обнаружил, что для has_many существуют обратные вызовы, поэтому я думаю, что могу определить отношения следующим образом:

has_many :awesome_friends,
         :class_name => "Friend",
         :conditions => {:awesome => true},
         :before_add => Proc.new{|p,c| c.awesome = true},
         :before_remove => Proc.new{|p,c| c.awesome = false}

Хотя, мне начинает казаться, что я просто внедряю какой-то другой существующий шаблон проектирования. Может быть, я должен подкласс AwesomeFriend <Друг? В конечном счете, мне нужна пара таких отношений has_many, и подклассы get запутались со всеми дополнительными файлами. </p>

РЕДАКТИРОВАТЬ 2:

Хорошо, спасибо всем, кто прокомментировал! В конечном итоге я обернул вышеописанный метод в приятное небольшое расширение ActiveRecord, has_many_of_type. Который работает следующим образом:

has_many_of_type :awesome_friends, :class_name => "Friend", :type=>:awesome

Это просто переводит has_many с соответствующими условиями, before_add и before_remove params (и предполагает существование столбца с именем friend_type).

Ответы [ 3 ]

3 голосов
/ 26 апреля 2011

Вам нужно использовать:

my_user.awesome_friends.create(:name=>'jim') или my_user.awesome_friends.build(:name=>'jim')

В документации: has_many (: условия)

Записи создания из ассоциации ограничены, если используется хеш. has_many: posts,: условие => {: опубликовано => true} создаст опубликованные сообщения с @ blog.posts.create или @ blog.posts.build.

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

Это не ошибка, я не думаю.Хеш: условия только определяет, как вы запрашиваете объекты.Но я не думаю, что рационально просто предполагать, что любой объект, который вы помещаете в коллекцию, может быть сделан для соответствия условиям.

В вашем простом примере это имеет смысл, но вытакже можно было бы использовать более сложную логику.

Документация также довольно ясна по этому вопросу:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

:conditions

Укажите условия, которым должен соответствовать связанный объект, чтобы быть включенным в качестве WHERE фрагмента SQL, например authorized = 1.

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

Это :class_name, а не :class, с одной стороны.

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