2011-08-11 90 views
0

我的嵌套模型表单现在正在工作,但我在显示视图中的数据时遇到了问题。如何显示具有一对多关系的嵌套模型数据?任何帮助将不胜感激。显示嵌套模型

这里是我的形式和控制器:

<%= form_for @account do |f| %> 

<%= f.label :account_type %><br /> 
<%= f.text_field :account_type %><br /> 

    <%= f.fields_for :organizations do |builder| %> 
     <%= builder.label :name %><br /> 
     <%= builder.text_field :name %><br /> 
     <%= builder.label :website %><br /> 
     <%= builder.text_field :website %><br /> 

     <%= builder.fields_for :locations do |lb| %> 
      <%= lb.label :phone %><br /> 
      <%= lb.text_field :phone %><br /> 
      <%= lb.label :toll_free_phone %><br /> 
      <%= lb.text_field :toll_free_phone %><br /> 
      <%= lb.label :fax %><br /> 
      <%= lb.text_field :fax %><br /> 

      <%= lb.fields_for :addresses do |ab| %> 
       <%= ab.label :address1 %><br /> 
       <%= ab.text_field :address1 %><br /> 
       <%= ab.label :address2 %><br /> 
       <%= ab.text_field :address2 %><br /> 
       <%= ab.label :city %><br /> 
       <%= ab.text_field :city %><br /> 
       <%= ab.label :state %><br /> 
       <%= ab.text_field :state %><br /> 
       <%= ab.label :zip %><br /> 
       <%= ab.text_field :zip %><br /> 
      <% end %> 
     <% end %> 
    <% end %> 

<%= f.submit "Add account" %> 
<% end %> 

class AccountsController < ApplicationController 

def show 
    @account = Account.find(params[:id]) 
    @organization = @account.organizations 
end 

def new 
    @account = Account.new 
    organization = @account.organizations.build 
    location = organization.locations.build 
    location.addresses.build 

    @header = "Create account" 
end 

def create 
    @account = Account.new(params[:account]) 
    if @account.save 
     flash[:success] = "Account added successfully" 
     render 'show' 
    else 
     render 'new' 
    end 
end 
end 

在一般情况下,我如何引用嵌套模型数据的视图时,有一个一对多的关系?我是否需要使用某种类型的“where子句”来指定孩子?

下面是一个简单的示例show.html.erb,我尝试显示刚创建的组织的名称。它不起作用。

<h1><%= @organization.name %></h1> 

渲染“秀”的行动与上述形式导致此错误创建一个帐户后:

NoMethodError in Accounts#create 

Showing C:/Documents and Settings/Corey Quillen/My  
Documents/rails_projects/shop_manager/app/views/accounts/show.html.erb where line #1  
raised: 

undefined method `name' for nil:NilClass 
Extracted source (around line #1): 

1: <h1><%= @organization.name %></h1> 
Rails.root: C:/Documents and Settings/Corey Quillen/My  
Documents/rails_projects/shop_manager 

Application Trace | Framework Trace | Full Trace 
app/views/accounts/show.html.erb:1:in  
`_app_views_accounts_show_html_erb__790921876_14235864__946051513' 
app/controllers/accounts_controller.rb:21:in `create' 
Request 

Parameters: 

{"utf8"=>"✓", 
"authenticity_token"=>"y59rGAhS+kqfH3v3axhlYuxvBbBxIWXg0yucCFwfBq8=", 
"account"=>{"account_type"=>"dfdf", 
"organizations_attributes"=>{"0"=>{"name"=>"dfdf", 
"website"=>"dfdf", 
"locations_attributes"=>{"0"=>{"phone"=>"dfdf", 
"toll_free_phone"=>"dfd", 
"fax"=>"", 
"addresses_attributes"=>{"0"=>{"address1"=>"", 
"address2"=>"", 
"city"=>"", 
"state"=>"", 
"zip"=>""}}}}}}}, 
"commit"=>"Add account"} 
+1

您是否也可以为您的show动作发布控制器代码? – Msencenb

+0

您可能正在执行'render show'而不是'redirect_to ...'。所以,是的,请向我们展示您的控制器代码。 – Mischa

回答

0

您在演出动作中说@organization = @ account.organizations。 你期望@organization包含什么? 想一想。这将是一个阵列不是一个单一的组织,如此循环,并获得每个组织的名称

其实我认为你没有想到你的关系,通过正确的帐户belongs_to一个组织。你真的想要一个帐户与多个组织关联吗?

UPDATE - Ref comment below 完全可以这样做,但您需要决定什么是业务逻辑,它决定了哪些组织需要在此显示。 如果你能确切地解释你的关系应该如何工作应该不会太难向你展示如何运用你的逻辑

更新 - 如何让基层组织

这是一个简单的在你的节目行动帐户模型建立一个新的关联

has_one :primary_organization. 
     :class_name => 'Organization', 
     :conditions => ['primary = ?', true] 

随后的事情就写

@account.primary_organization.first #because anything use on a find other than the primary key will always return an array even if there is only one record. 

您可能还想检查primary_organization是否为空? 考虑将has_one重构为类方法。根据您的需求可能不需要 更多此处了解http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

+0

我确实想保持帐户和组织之间的一对多关系。有没有办法通过数据库属性指定特定的帐户? –

+0

我的组织表中有一个'主'布尔列。每个账户只有一个组织会被标记为“真实”。我如何使用@ account.organizations调用指定?我可以链接到它的方法吗?谢谢。 –

+0

好的,太好了。这听起来像我在找什么。感谢你的帮助。 –

0

当你的关系是一个一对多的,你必须使用

@organization.first.name 

它会显示第一个组织。

as @organization是一个数组,您必须收集所有名称然后显示。

+0

这有效,但如果我想指定除第一个以外的其他组织,该怎么办? –