undefined方法`each'表示“#<complaigns :: activerecord_relation:0x00000003cfb4c8>”:String

时间:2015-07-16 07:10:04

标签: ruby-on-rails ruby ruby-on-rails-4

我有一个名为Complaign的模型,其中包含一些其他属性以及抱怨日期(c_date)。

ComplaignController中,我有一个index视图,其中显示了所有complaigns。从日期到日期都有一个过滤器。在过滤它时,它工作正常,并正确显示在这些日期触发的抱怨。

现在我想将此查询的结果传递给另一个方法,比如export方法。

我想过从索引视图中传递它,因为它存储在@complaigns

这是我的索引方法:

def index
        if params[:from] && params[:to]
            from = params[:from].to_date
            to = params[:to].to_date
            @complaigns = Complaigns.where(:c_date => from..to)
        else    
      @complaigns = Complaigns.all
        end    
  end

在索引视图中,这是我写的

<%= link_to "Export", {:controller => "complaigns", :action => "export", :complaigns => @complaigns}%>

这是导出方法

def export
         @complaigns = params[:complaigns]
  end

现在,在导出视图中,当我执行以下操作时:

@complaigns.each,我收到此错误 -

undefined method `each' for "#<Complaign::ActiveRecord_Relation:0x00000003cfb4c8>":String

现在这是因为,我认为each类中没有方法String。有没有办法,我可以在方法export中将String转换为Complaign类型,或者在从索引视图传递它时,将其作为Complaign对象而不是String传递?还有其他方法吗?

4 个答案:

答案 0 :(得分:2)

您无法直接在控制器参数中传递Ruby on Rails模型对象,您可以传递相应的ID,然后从数据库加载模型。 HTTP / Ruby on Rails是无状态的。如果你总是在导出之前去索引,那么解决这个问题的一种方法可能是:

<%= link_to "Export", {:controller => "complaigns", :action => "export", :complaigns => @complaigns.map(&:id)}%>

def export
         @complaigns = Complaigns.find(params[:complaigns])
end

答案 1 :(得分:0)

看起来@complaigs是作为字符串而不是实际的active_record关系对象传递的。您应该在导出中计算@camplaigs而不是发送它们。或者你可以传递数组

@complaigns.collect(&:id)

答案 2 :(得分:0)

HTTP是无状态协议,这意味着每个请求都独立于另一个(除非您使用cookie或会话)。对于导出方法,除非您向其传递足够的信息,否则它对索引方法的结果一无所知。所以一个简单的解决方案可以是:

索引视图

<%= link_to "Export", {:controller => "complaigns", :action => "export", :from => params[:from], :to => params[:to] }%>

导出方法

def export
  if params[:from] && params[:to]
    from = params[:from].to_date
    to = params[:to].to_date
    @complaigns = Complaigns.where(:c_date => from..to)
  else    
    @complaigns = Complaigns.all
  end    
end

此处,索引的参数会传递给导出

但这种方法不够DRY。您可以考虑使用索引进行导出,如下所示:

def index
  if params[:from] && params[:to]
    from = params[:from].to_date
    to = params[:to].to_date
    @complaigns = Complaigns.where(:c_date => from..to)
  else    
    @complaigns = Complaigns.all
  end
  if params[:export].present?
     render 'export'
  else
     render 'index'
  end
end

然后在导出链接中,您可以使用:

<%= link_to "Export", {:controller => "complaigns", :action => "index", :from => params[:from], :to => params[:to], :export => true }%>

PS。这些代码未经过测试。仅供演示之用。

答案 3 :(得分:0)

你无法做你想做的事。问题是,在渲染视图时,生成的HTML是文本,因此@complaigns会转换为它的等效文本(与@ complaigns.to_s相同)。

要做你想做的事,你需要传递给你的链接,你用来在索引视图中创建@camplaigns的相同参数。所以:

将您的链接更改为:

<%= link_to "Export", {:controller => "complaigns", :action => "export", :to => params[:to], :from => params[:from]}%>

然后将导出方法更改为:

def export
  index
end