Типы Ruby наборов в ActiveRecord

Попробуйте это.

<asp:Button id="myButton" runat="server" style="display:none" Text="Click Me" />

<script type="text/javascript">
    function ShowButton() {
        var buttonID = '<%= myButton.ClientID %>';
        var button = document.getElementById(buttonID);
        if(button) { button.style.display = 'inherit'; }
    }
</script>

не используют серверный код, чтобы сделать это, потому что это потребовало бы обратной передачи. Вместо того, чтобы использовать Видимость = "ложь", можно просто установить свойство CSS, которое скрывает кнопку. Затем в JavaScript, переключатель, что свойство назад каждый раз, когда Вы хотите показать кнопку снова.

ClientID используется, потому что это может отличаться от идентификатора сервера, если кнопка в управлении Именованным контейнером. Они включают Панели различных видов.

10
задан kmorris511 23 March 2010 в 20:41
поделиться

3 ответа

Как говорили другие, объект ассоциации на самом деле не является массивом. Чтобы узнать настоящий класс, сделайте это в irb:

class << foo_instance.bars
  self
end
# => #<Class:#<ActiveRecord::Associations::HasManyAssociation:0x1704684>>

ActiveRecord::Associations::HasManyAssociation.ancestors
# => [ActiveRecord::Associations::HasManyAssociation, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Associations::AssociationProxy, Object, Kernel]

Чтобы избавиться от метода ActiveRecord :: Bse # find, который вызывается, когда вы выполняете foo_instance.bars.find (), поможет следующее:

class << foo_instance.bars
  undef find
end
foo_instance.bars.find {...} # Array#find is now called

This потому что класс AssociationProxy делегирует все методы, о которых он не знает (через method_missing), своему #target, который является фактическим базовым экземпляром массива.

6
ответ дан 3 December 2019 в 20:43
поделиться

Я полагаю, это потому, что ActiveRecord похитил метод find для собственные цели.

Это не совсем настоящее объяснение. foo_instance.bars возвращает не экземпляр массива, а экземпляр ActiveRecord :: Associates :: AssociationProxy . Это специальный класс, предназначенный для работы в качестве посредника между объектом, который содержит ассоциацию, и связанным с ней.

Объект AssociatioProxy действует как массив, но на самом деле это не массив. Следующие детали взяты непосредственно из документации.

# Association proxies in Active Record are middlemen between the object that
# holds the association, known as the <tt>@owner</tt>, and the actual associated
# object, known as the <tt>@target</tt>. The kind of association any proxy is
# about is available in <tt>@reflection</tt>. That's an instance of the class
# ActiveRecord::Reflection::AssociationReflection.
#
# For example, given
#
#   class Blog < ActiveRecord::Base
#     has_many :posts
#   end
#
#   blog = Blog.find(:first)
#
# the association proxy in <tt>blog.posts</tt> has the object in +blog+ as
# <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
# the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
#
# This class has most of the basic instance methods removed, and delegates
# unknown methods to <tt>@target</tt> via <tt>method_missing</tt>. As a
# corner case, it even removes the +class+ method and that's why you get
#
#   blog.posts.class # => Array
#
# though the object behind <tt>blog.posts</tt> is not an Array, but an
# ActiveRecord::Associations::HasManyAssociation.
#
# The <tt>@target</tt> object is not \loaded until needed. For example,
#
#   blog.posts.count
#
# is computed directly through SQL and does not trigger by itself the
# instantiation of the actual post records.

Если вы хотите работать с массивом результатов, вам вообще не нужны навыки метапрограммирования. Просто сделайте запрос и убедитесь, что метод find вызывается на реальном объекте Array, а не на экземпляре, который крякает, как массив .

foo_instance.bars.all.find { ... }

Метод all является методом поиска ActiveRecord (ярлык для find (: all)). Он возвращает массив результатов. Затем вы можете вызвать метод Array # find для экземпляра массива.

9
ответ дан 3 December 2019 в 20:43
поделиться

Ассоциации ActiveRecord на самом деле являются экземплярами Reflection, который переопределяет instance_of? и связанные методы, чтобы лгать о том, что это за класс. Вот почему вы можете делать такие вещи, как добавление именованных областей (скажем, «недавние») и последующий вызов foo_instance.bars.recent. Если бы "bars" был массивом, это было бы довольно сложно.

Попробуйте проверить исходный код ("locate Reflection.rb" должен найти его в любом unix-ish-боксе). Чад Фаулер сделал очень информативный доклад на эту тему, но я не могу найти никаких ссылок на него в Интернете. (Кто-нибудь хочет отредактировать этот пост, чтобы включить его?)

3
ответ дан 3 December 2019 в 20:43
поделиться
Другие вопросы по тегам:

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