Что является целью: условия на belongs_to ассоциации?

Скажите, что у меня есть следующая связь с приложенным условием:

belongs_to :admin_user, 
    :class_name => 'User', 
    :foreign_key => :admin_user_id, 
    :conditions=> 'users.admin=TRUE' # or any variation with hash or array, {:admin => true}, etc.

Документ API указывает что: опция условий на belongs_to будет:

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

Но вывод не показывает оператора Where на выборе, и в любом случае я ожидал бы, что условия как это на belongs_to предотвратят сохранение что отношения для начала на ВСТАВКЕ не ВЫБОР. Эта опция, кажется, не имеет никакого эффекта на belongs_to ассоциацию, если я не пропускаю что-то. Опция имеет смысл на has_many, я просто не вижу, как это относится к belongs_to.

Править: Дальнейшее исследование показывает, что можно действительно сохранить ассоциацию, которая нарушает условие, но Вы не можете получить связанную запись после того, как запись перезагружается.

На классе, определенном как так:

class Widget < ActiveRecord::Base

    belongs_to :big_bloop, 
        :class_name => "Bloop", 
        :foreign_key => :big_bloop_id, 
        :conditions => ["big_bloop = ?", true]

    belongs_to :bloop, :conditions => ["big_bloop = ?", true]

end

... от консоли мы видим:

>> bloop = Bloop.new
=> #
>> widget = Widget.new
=> #
>> widget.bloop = bloop
=> #
>> widget.save!
=> true
>> widget
=> #

Я связал завывание, которое нарушает условие и сохранило его. Ассоциация сохраняется к дб (см. bloop_id и big_bloop_id на последней строке выше).

>> big_bloop = Bloop.new
=> #
>> widget.big_bloop = big_bloop
=> #
>> widget.save!
=> true
>> widget
=> #

То же самое, другой атрибут.

>> widget.bloop
=> #
>> widget.big_bloop
=> #

Оба недопустимых завывания остаются в памяти.

>> widget.reload
=> #
>> widget.bloop
=> nil
>> widget.big_bloop
=> nil

После перезагрузки их не стало, потому что оператор SELECT действительно использует оператор Where для исключения их.

Bloop Load (0.3ms)   SELECT * FROM `bloops` WHERE (`bloops`.`id` = 2 AND (big_bloop = 1)) 

И все же виджет все еще имеет ссылки:

>> widget
=> #

Кажется нечетным мне, но там Вы идете.

7
задан Dave Sims 28 January 2010 в 20:14
поделиться

1 ответ

Михаэль Марчик абсолютно корректен в вопросе о фондах и совпадении экземпляров, и тип обертки кажется простым исправлением. С другой стороны, если вы уже читаете сайт Олега, вы можете предпочесть пойти глубже вниз по кроличьей норе и попробовать написать экземпляр для «любого типа, который не является функцией».

При переходе к UndecidureInstances условие покрытия описывается здесь ; должно быть очевидно, почему ваши экземпляры не справляются с этим. Обратите внимание, что слово «undecidable» здесь означает undecidable примерно в том же смысле, что и в «Halting Problem is undecidable» --это сказать, вы говорите GHC безрассудно пытаться разрешить код, который может отправить его в бесконечный цикл на основе только вашего утверждения, что это нормально. Это весело для взлома аккуратных идей, но согласие быть человеком, первым проходящим проверку типа для GHC - это бремя, которое я лично нахожу усталым.

-121--2409083-

Маги - единственная, которую я могу найти, которая не сосредоточена на OpenGL. Если вы планируете многопользовательскую игру, ее стоит проверить.

-121--2619163-

Это хорошая находка!

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

@@valid_keys_for_belongs_to_association = [
  :class_name, :primary_key, :foreign_key, :foreign_type, :remote, :select, :conditions,
  :include, :dependent, :counter_cache, :extend, :polymorphic, :readonly,
  :validate, :touch
]

Так что в какой-то точка было принято возможно подсознательное решение поместить это туда.:)

Я не уверен, как вы протестировали WHERE, хотя. Мое тестирование ясно показывает, что включает предложение WHERE:

class Thing < ActiveRecord::Base; end

class Widget < ActiveRecord::Base
  belongs_to :thing, :conditions => ['name = ?', 'Jigglymabob']
end

Thing.create :name => 'Jigglymabob'
# => #<Thing id: 1, name: "Jigglymabob">
w = Widget.create :name => 'Wookeleywoo', :thing_id => 1
# => #<Widget id: 1, name: "Wookeleywoo", thing_id: 1>
w.thing
# => #<Thing id: 1, name: "Jigglymabob">

После всего этого мой файл журнала содержит:

Thing Create (0.3ms)   INSERT INTO "things" ("name") VALUES('Jigglymabob')
Widget Create (0.3ms)   INSERT INTO "widgets" ("name", "thing_id") VALUES('Wookeleywoo', 1)
Thing Load (0.6ms)   SELECT * FROM "things" WHERE ("things"."id" = 1 AND (name = 'Jigglymabob'))

Когда я пытаюсь набрать это для вас, я понял, что до сих пор не дал реального ответа на ваш вопрос.:) Я могу придумать только одну причину, чтобы это было в ActiveRecord, и это потому, что это не было лишних хлопот для реализации, и нет никакой пользы, чтобы оставить это.

Кто-то может работать над странным краевым футляром с устаревшей базой данных, где золотое правило в офисе - что каждый учится трудному пути - никогда не имеет виджета Wookeleywoo, прикрепленного к чему-либо, кроме Jigglymabob.

4
ответ дан 7 December 2019 в 14:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: