以1种形式验证2个模型

时间:2013-02-22 09:30:13

标签: ruby ruby-on-rails-3 validation nested-forms

我正在学习RoR,但我无法找到以相同形式验证模型的方法。它正在验证,但它只显示一个模型(地址)的错误消息,并且它正在填充另一个模型的其他输入字段,就像更改之前一样。我尝试过一些东西,但没有一个能奏效。

在edit.html.erb中我显示错误消息。仅当一个模型不正确时才能正常工作。如果两个模型中的输入都不正确,我只会看到地址的错误信息,并且相关的输入字段将使用之前的值重置。

我认为这就是你真正需要的。我的地址控制器是空的。除了验证之外,其他所有工作都正常。

的Mathias。

Edit.html.erb:

<h1>Edit Mutuality</h1>

<%= form_for @mutuality do |f| %>
<%= fields_for @address do |fa| %>
    <% if @mutuality.errors.any? %>
        <h2>Errors:</h2>
        <ul>
            <% @mutuality.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    <% end %>
    <% if @address.errors.any? %>
        <h2>Errors:</h2>
        <ul>
            <% @address.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    <% end %>
<table>
    <tr>
        <td>
            <%= f.label :name %>
        </td>
        <td>
            <%= f.text_field :name %>
        </td>
    </tr>
    <tr>
        <td>
            <%= f.label :phone %>
        </td>
        <td>
            <%= f.text_field :phone %>
        </td>
    </tr>
    <tr>
        <td>
            <%= f.label :contact %>
        </td>
        <td>
            <%= f.text_field :contact %>
        </td>
    </tr>
    <tr>
        <td>
            <%= fa.label :street %>
        </td>
        <td>
            <%= fa.text_field :street %>
        </td>
    </tr>
    <tr>
        <td>
            <%= fa.label :number %>
        </td>
        <td>
            <%= fa.text_field :number %>
        </td>
    </tr>
    <tr>
        <td>
            <%= fa.label :zipcode %>
        </td>
        <td>
            <%= fa.text_field :zipcode %>
        </td>
    </tr>
    <tr>
        <td>
            <%= fa.label :city %>
        </td>
        <td>
            <%= fa.text_field :city %>
        </td>
    </tr>
    <tr>
        <td>
            &nbsp;
        </td>
        <td>
            <%= f.submit %>
        </td>
    </tr>
</table>
<% end %>

    

控制器:

class MutualitiesController < ApplicationController

def index
    @mutualities = Mutuality.all
  end

  def show
    @mutuality = Mutuality.find(params[:id])
  end

  def new
    @mutuality = Mutuality.new
    @address = Address.new
  end

  def create
    @mutuality = Mutuality.new(params[:mutuality])
    @address = Address.new(params[:address])

    if @address.save
      @mutuality.address_id = @address.id
      if @mutuality.save
        redirect_to mutualities_path, :notice => "Mutuality saved with succes!"
      else
        render "new"
      end
    else
      render "new"
    end    
  end

  def edit
    @mutuality = Mutuality.find(params[:id])
    @address = Address.find(@mutuality.address_id)
  end

  def update
    @mutuality = Mutuality.find(params[:id])
    @address = Address.find(@mutuality.address_id)

    if @address.update_attributes(params[:address])
      if @mutuality.update_attributes(params[:mutuality])
        redirect_to mutualities_path, :notice => "Mutuality updated with succes!"
      else
        render "edit"
      end
    else
      render "edit"
    end

  end

  def destroy
    @mutuality = Mutuality.find(params[:id])
    @address = Address.find(@mutuality.address_id)
    @mutuality.destroy
    @address.destroy
    redirect_to mutualities_path
  end

end

2 个答案:

答案 0 :(得分:0)

Rails可以自动处理嵌套属性。你是手动完成的。 不确定您是否正确定义了模型中的关联。

所以,在你的模型中你应该写:

class Mutuality
  belongs_to :address
  accepts_nested_attributes_for :address
end

然后在你的控制器中你可以写:

def create
  @mutuality = Mutuality.new(params[:mutuality])

  if @mutuality.save
    redirect_to mutualities_path, :notice => "Mutuality saved with succes!"
  else
    render "new"
  end
end    

HTH。

答案 1 :(得分:0)

我终于成功了!我做了Nathanvda告诉我的更改,但我必须添加一些东西才能使它工作。还有一个小问题。我无法删除该地址。它只删除了Mutuality。有什么想法吗?

Address.rb

class Address < ActiveRecord::Base
  #attr_accessible :street, :number, :zipcode, :city
  attr_protected :id

  has_one :mutuality

  validates_presence_of :street, :number, :city

end

Mutuality.rb

class Mutuality < ActiveRecord::Base
  #attr_accessible :name, :phone, :contact, :address_id
  attr_protected :id, :address_id

  belongs_to :address
  accepts_nested_attributes_for :address, :allow_destroy => true

  validates_presence_of :name, :phone, :contact
  validates_length_of :name, :minimum => 5
  validates_uniqueness_of :name

end

这是我在show.html.erb上使用的链接:

<p>
    <%= link_to "Back", mutualities_path %> |
    <%= link_to "Edit", edit_mutuality_path %> |
    <%= link_to "Delete", @mutuality, :confirm => "You are going to delete " +  @mutuality.name + ". Do you wish to continue?", :method => :delete %>
</p>

这是破坏功能:

  def destroy
    @mutuality = Mutuality.find(params[:id])
    if @mutuality.destroy
      redirect_to mutualities_path, :notice => "Mutuality deleted with succes!"
    else
       redirect_to mutualities_path, :error => "A problem has occured."
    end
  end

的Mathias