Rails嵌套模型表单:验证外键的存在,除非用户创建新记录

时间:2010-12-14 20:19:17

标签: ruby-on-rails

有一个非常简单的rails应用程序,这是我的代码:

class Post < ActiveRecord::Base
  belongs_to :category
  attr_accessible :category_id, :category_attributes    
  accepts_nested_attributes_for :category, :reject_if => :all_blank
end

class Category < ActiveRecord::Base
  has_many :posts
end

#app/views/posts/_form.html.haml
= simple_form_for(@post) do |f|
  = f.association :category
  = f.simple_fields_for :category do |cat_f|
    = cat_f.input :name    

因此,在创建新帖子时,我可以选择一个类别(从选择菜单中)或创建一个新类别(如果它不存在)。

我想验证是否存在 category_id ,除非用户选择创建新类别

我猜测有一种解决这个问题的方法 - 我知道我不能只添加validates :category_id, :presence => true,因为当用户决定创建一个新类别时,这会导致表单提交失败(并且不从下拉列表中选择一个。

第二个问题: 我最近阅读了一个有用的rails教程,向您展示如何在显示类别选择菜单和新类别字段之间切换,以便在任何给定时间屏幕上只显示其中一个。任何人都有这样的链接吗?

2 个答案:

答案 0 :(得分:11)

我想我已经通过替换:

解决了这个问题
validates :category_id, :presence => true

validates :category, :presence => true

似乎有效。 奇怪的一个。

PS

我只能想象这是有效的,因为如果用户从下拉列表 OR 中选择某些内容,如果他们使用嵌套表单创建新类别,则认为:category存在,而以前,使用我的原始代码::category_id仅在用户从下拉菜单中选择内容时才被视为存在,而 NOT 在创建新记录时被视为

答案 1 :(得分:0)

在PostsController中,您可能希望检查创建操作中的传入参数,以查看category_id是否为默认值(此处为-1),如果是,则从文本字段创建新类别。像这样:

def create
  if params[:post][:category_id] != -1
    category = Category.create params[:post][:category_name]
    # make sure category is attached to post
  end

  # rest of your create action
end

更新操作中的类似内容。

至于你的第二个问题,那可能是更少的Rails,更好地通过Javascript处理。您可以很容易地使用单选按钮来使用现有类别&#39;或者&#39;创建新类别&#39;,然后使用javascript正确交换DOM对象。