在活动记录关联你怎么只引用了持久记录 [英] How do you reference only the persisted records in an active record association
问题描述
在多个控制器的编辑方法初始化一个新的对象,并编辑现有的对象
In the edit method of many controllers you initialize a new object and edit existing objects
class MagazinesController < ApplicationController
def edit
@magazine = Magazine.find(params[:magazine_id])
@page = Page.find(params[:id])
@new_page = @magazine.pages.new
end
end
然而,在一个视图中,你会经常要循环持久化对象,并单独处理的新对象。
However in a view you will often want to cycle through the persisted objects and treat the new object separately
# magazines#edit
%h4 Existing pages
- @magazine.pages.each do |page|
%p= link_to page, page.title
问题
...是,页
关联包含现有的(持续)页,而且我们通过 @new_page = @取得了新的一页magazine.pages.new
。
The problem
...is that the pages
association contains both existing (persisted) pages but also the new page which we made via @new_page = @magazine.pages.new
.
可以很容易地处理这种但是它的丑陋
It's easy to deal with this however it's ugly
%h4 Existing pages
- @magazine.pages.each do |page|
- if page.persisted?
%p= link_to page, page.title
我想用一些协会[方法来选择只有那些持续网页:
I would like to use some assocition method to select only those pages which are persisted:
%h4 Existing pages
- @magazine.pages.persisted.each do |page|
%p= link_to page, page.title
有没有办法这样做的?
Is there any way of doing this?
推荐答案
无论从@ Florent2和@CDub的建议是合理的。然而@ florent2的建议意味着再次命中数据库(可能抛弃任何preset的,我不想做预先加载)和@ CDub的建议并没有完全制定出在code条款。以下是我结束了去:
Both the suggestions from @Florent2 and @CDub are sound. However @florent2's suggestion meant hitting the database again (and potentially ditching any preset eager loading which I didn't want to do) and @CDub's suggestion didn't quite work out in terms of code. Here is what I ended up going with:
class Magazine < ActiveRecord::Base
has_many :pages do
def persisted
collect{ |page| page if page.persisted? }
end
end
end
这允许你调用 .persisted
在与杂志有关的网页的任何ActiveRecord的关系。它不会再次访问数据库,因为它只需通过pre-加载的对象返回它们坚持的那些过滤器。
this allows you to call .persisted
on any ActiveRecord relation of pages associated with Magazine. It doesn't hit the database again as it simply filters through the pre-loaded objects returning the ones which are persisted.
因为我想重新使用此code定期,我可以拉出来变成一个模块
Since I want to reuse this code on a regular basis I can pull it out into a module
module PersistedExtension
def persisted
select{|item| item if item.persisted?}
end
end
有然后可以纳入使用一个lambda关联方法:
It can then be included into the association methods using a lambda:
class Magazine < ActiveRecord::Base
# ...
has_many :pages, -> { extending PersistedExtension }
end
和我能直观地叫它:
@magazine = Magazine.first
@magazine.pages.persisted
# => array of pages which are persisted
# the new persisted association extension works on any AR result set
@magazine.pages.order('page ASC').persisted
这篇关于在活动记录关联你怎么只引用了持久记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!