Могу ли я получить доступ к идентификатору родительского объекта внутри named_scope при извлечении связанных объектов с помощью метода 'others'? - PullRequest
3 голосов
/ 02 февраля 2010

Допустим, у вас есть две модели: articles и comments.

class Article < ActiveRecord::Base
  has_many :comments
end

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

article = Article.first
article.comments # => SELECT * FROM "comments" WHERE ("comments".article_id = 123)

Есть ли способ явного доступа к article_id (123) в named_scope?

Мне это нужно для комплекса named_scope, который присоединяется к другой таблице. По сути, named_scope будет иметь смысл вызываться из ассоциированного родительского объекта (article.comments.my_named_scope и , а не Comments.my_named_scope).

Я не хочу передавать идентификатор в качестве параметра для named_scope. Итак, вместо передачи article_id в именованную область с помощью ... lambda { |article| ...} и доступа к идентификатору с помощью "... #{article.id} ...", я хочу каким-то образом получить доступ к этому article_id, который использует others метод , Я получаю от has_many ассоциации.

Ответы [ 4 ]

4 голосов
/ 02 февраля 2010

Похоже, что вы на самом деле ищете расширение ассоциации: http://guides.rubyonrails.org/association_basics.html#association-extensions

В частности, proxy_owner, который будет @article в вопросе

например:

class Article < ActiveRecord::Base
  has_many :posts do
    def sample_extension
      puts "Proxy Owner #{proxy_owner}"
    end
  end
end

@article.posts.sample_extension
2 голосов
/ 10 мая 2011

боролся с той же проблемой. Вы можете попробовать это, что более элегантно, чем использование расширений ассоциации:

class Article < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  def self.get_article_id
    self.new.article_id
  end
end

@article = Article.new
@article.posts.get_article_id

В методах класса для Post теперь вы можете просто использовать get_article_id везде, где вам нужен идентификатор родительской статьи. С ассоциациями прокси я не смог этого сделать.

0 голосов
/ 08 января 2016

Для рельсов 4 и выше

Более новый способ сделать это в Rails4 +:

class Article < ActiveRecord::Base
  has_many :comments do
    def my_named_scope
      puts "Scope Owner = #{@association.owner}"
    end
  end
end

article = @article.comments.my_named_scope

Внутри области действия my_named_scope, @association.owner возвращает объект Article, для которого был вызван .comments. Следовательно, article, возвращаемый приведенным выше кодом, совпадает с объектом @article.

Альтернативный метод

Если вы не хотите использовать расширения и предпочитаете избегать метода «создайте новый объект и получите идентификатор оттуда» (как описано в ответе Chanpory), вот как это сделать:

class Article < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  def self.get_article_id
    Comment.scope_attributes["article_id"] # scope_attributes returns a hash of all the attributes inherited from the owner of this scope
  end
end

@article = Article.find(10)
@article.comments.get_article_id  # returns 10
0 голосов
/ 30 апреля 2014

Мне нравится решение @ ajkochanowicz, но похоже, что там задействовано попадание в БД (Rails 3.2.x), так что просто наперед, не совсем идеально, учитывая тот факт, что у вас уже есть родительский объект под рукой.

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