在活动记录关联你怎么只引用了持久记录 [英] How do you reference only the persisted records in an active record association

查看:107
本文介绍了在活动记录关联你怎么只引用了持久记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在多个控制器的编辑方法初始化一个新的对象,并编辑现有的对象

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆