rails from Japan
rails from Japan

Reputation: 11

Rails 4 fields_for not saving

I'd like to save article_id in photos model via fields_for but doesn't work.

article.rb

class Article < ActiveRecord::Base
    belongs_to :user
    belongs_to :category
    has_many :photos
    accepts_nested_attributes_for :photos

photo.rb:

class Photo < ActiveRecord::Base
    belongs_to :article

category.rb

class Category < ActiveRecord::Base
    has_many :articles

  articles_controller.rb

class ArticlesController < ApplicationController

  def new
    @article = Article.new
    @category  = Category.find(params[:category])
    @article.photos.build
  end

  def create
    @article = current_user.articles.build(article_params)
    @article.save

   |
   |
   |

private

def article_params
    params.require(:article).permit(:content, :category_id, photos_attributes: [:id, :article_id])
end

_article_form.html.erb

<%= form_for(@article) do |f| %>
    <%= f.hidden_field :category_id %>
    <%= f.text_area :content %>
    <%= f.fields_for :photos do |p| %>
      <%= p.hidden_field :article_id %>
    <% end %>
  <%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>

.schema articles

CREATE TABLE "articles" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
"content" varchar(255), 
"user_id" integer, 
"category_id" integer,
"created_at" datetime, 
"updated_at" datetime);

.schema categories

CREATE TABLE "categories" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
"code" integer, 
"created_at" datetime, 
"updated_at" datetime);

Thanks rmagnum2002.

In articles_controller.rb, I added as followings;

private

def article_params
    params.require(:article).permit(:content)
end

But I didn't have article_id. How can I write code for article_id?


Thanks Rich Peck.

Althogh I edited articles_controller.rb, I had NoMethodError in ArticlesController#new. undefined method `build_photo' for #

articles_controller.rb

  def new
    @article = Article.new
    @article.build_photo

Upvotes: 1

Views: 325

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

<%= f.fields_for :photo do |p| %>

We had this issue a few months back; fields_for is part of your form_for object, and consequently won't submit unless it's called on the form object (with f.).

The rails guide is very misleading with this method - you need to call it with f. to get it to pass the data to your params.

--

Controller

If you're using f.fields_for, you also need to build your associative data in your controller:

#app/controllers/articles_controller.rb
Class ArticlesController < ApplicationController
   def new
      @article = Article.new
      @article.build_photo #-> build_value is for singluar association; values.build is for multiple
   end

   def create
      @aticle = Article.new(article_params)
      @article.save
   end

   private 

   def article_params
       params.require(:article).permit(photo_attributes: [:your, :attributes])
   end
end

Upvotes: 1

Related Questions