开发者

Rails nested model forms: validate presence of foreign key unless user creates new record

In have a pretty simple rails app, here's my code:

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    

So when creating a new post, I have the option to choose a category (from the select menu) or create a new one (if it doesn't exist).

I want to validate that category_id is present, unless the user opts to create a new category

I'm guessing there's some kind of rails way to solve this problem - I know that I can't just add validates :category_id, :presence => true as this will cause form submission to fail when the user decides to create a new category (and doesn't select one from the drop-down).

Second Question: I recently read a useful rails tutorial that showed you how to toggle between displaying the category select menu and the new category fields so that only one of the tw开发者_如何学Pythono is present on screen at any given time. Anyone got a link to something like that?


I think I have fixed this by replacing:

validates :category_id, :presence => true

with

validates :category, :presence => true

It seems to work. Strange one.

PS

I can only imagine that this works because :category is considered present if the user selects something from the drop-down list OR if they create a new category using the nested form, whereas previously, with my original code, :category_id was only considered present when the user selected something from the drop-down and NOT when they created a new record.


In your PostsController, you probably want to check the incoming parameters in your create action to see if category_id is your default value (here, -1), and if so, create a new category from the text field. Something like this:

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

And something similar in your update action.

As for your second question, that's probably less Rails and better handled by Javascript. You could pretty easily have a radio button for 'use existing category' or 'create new category', and then use javascript to swap the DOM objects appropriately.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜