在许多控制器的edit方法中,您可以初始化一个新对象并编辑现有对象
class MagazinesController < ApplicationController
def edit
@magazine = Magazine.find(params[:magazine_id])
@page = Page.find(params[:id])
@new_page = @magazine.pages.new
end
end
但是,在视图中,您通常需要循环浏览持久化对象并分别对待新对象
# magazines#edit
%h4 Existing pages
- @magazine.pages.each do |page|
%p= link_to page, page.title
...是该pages
关联既包含现有(持久)页面,又包含我们通过创建的新页面@new_page = @magazine.pages.new
。
这很容易处理,但是很难看
%h4 Existing pages
- @magazine.pages.each do |page|
- if page.persisted?
%p= link_to page, page.title
我想使用某种关联方法仅选择那些持久化的页面:
%h4 Existing pages
- @magazine.pages.persisted.each do |page|
%p= link_to page, page.title
有什么办法吗?
@ Florent2和@CDub的建议都是正确的。但是,@ florent2的建议意味着再次命中数据库(并可能放弃了我不想做的任何预设的紧急加载),而@CDub的建议在代码方面还不太可行。这就是我最终要进行的工作:
class Magazine < ActiveRecord::Base
has_many :pages do
def persisted
collect{ |page| page if page.persisted? }
end
end
end
这使您可以调用.persisted
与Magazine关联的页面的任何ActiveRecord关系。它不会再次访问数据库,因为它只过滤了预加载的对象并返回保留的对象。
由于我想定期重用此代码,因此可以将其拉入模块
module PersistedExtension
def persisted
select{|item| item if item.persisted?}
end
end
然后可以使用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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句