August 09, 2009
fields_for in Rails, but no one mentions it
I was laying out a form for a page model last night. Each page has_many :contents. That’s straightforward enough, but when it came to the view I wanted to present the fields from page and the associated content model. That way the user can enter all of the necessary content, for both models, on a single page.
The Rails API explains fields_for very well, but there is no information on how the controller should act. I couldn’t find anything on the controller aspect anywhere. So this is what I’ve come up with.
The posted form looks like this.1 2 3 4 5 6 |
params = {
"page" => {
"name" => "My Sweet Page",
"content" => { " block"=> "This is why my page is so sweet" }
}
} |
You can’t just throw params[:page] into the Page model and save it because that will fail. It fails because content is an associated model and does not exist in the page table.
1 2 |
@page = Page.new(params[:page]) @page.save! # fails here |
What you’ll need to do is remove the content data from params before adding it to Page, but make sure you hold on to it so you can create the content block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
params_content = params[:page][:content] # get page content params[:page].delete :content # remove content from page @page = Page.new(params[:page]) # create the page content = @page.contents.build(params_content) # create the content if @page.valid? and content.valid? @page.save content.save flash[:notice] = "Your page has been sucessfully created." else flash[:error] = "There was a problem with the content you've entered." end |
This approach works pretty well. Alter the code to fit your needs, but this should work well enough for a prototype.
Leave a Comment