6

What I think is going on is that the :pledge attributes (:amount and :frequency)from my view is not getting passed to the new action in the controller. Also, I know that my pledge attributes are not saving and maybe that's because pledge_id is nil when calling @user.

new.html.erb

<%= form_for @user, url: pledge_path, controller: 'user', action:     'create', method: 'post' do |f| %>
  <%= f.label :user_name %>
  <%= f.text_area :user_name %>
  <%= f.label :email %>
  <%= f.text_area :email%>
  <%= f.label :address %>
  <%= f.text_area :address %>
  <%= f.fields_for(:pledge) do |b| %>
    <%= b.label :amount %>
    <%= b.text_area :amount %>
    <%= b.label :frequency %>
    <%= b.text_area :frequency %>
    <%= b.submit 'I also want o pledge' %>
  <% end %>
<%= f.submit 'I just want to sumbit my info' %>

<% end %>

pledge.rb

class Pledge < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user

end

user.rb

class User < ActiveRecord::Base
  has_many :pledges, foreign_key: "pledge_id"
   accepts_nested_attributes_for :pledges
   attr_accessor :pledges

end

schema.rb

ActiveRecord::Schema.define(version: 20150318161827) do

create_table "pledges", force: :cascade do |t|
  t.integer "frequency"
  t.float   "amount"
  t.integer "user_id"
end

add_index "pledges", ["user_id"], name: "index_pledges_on_user_id"

create_table "users", force: :cascade do |t|
  t.string  "user_name"
  t.string  "email"
  t.string  "address"
  t.integer "pledge_id"
end

end

user_controller.rb

class UserController < ApplicationController
def new
    @user = User.new
    @user.pledges.build 
end

def create
    if params[:commit] == 'I just want to sumbit my info'
        User.create(user_params)

    elsif
        @pledge = Pledge.new(params[:pledge])
        @pledge.save
        @user = User.create(pledge_params)  
    end
    redirect_to thank_you_path

end
def pledge_params
    params.require(:user).permit(:email, :user_name, :address,
                                pledge_attributes: [:id, :amount, :frequency])
end

def user_params
    params.require(:user).permit(:email, :user_name, :address)
end
end

Thanks in advance for any suggestions!

K Waters
  • 63
  • 1
  • 4

2 Answers2

18

Info from here was helful for me in similar case like yours.

So in code of Sontya you need to change @user.pledges.build to @user.build_pledges.

Although, i think you solved your issue, but i do this answer to help anyone who will search this info.

Community
  • 1
  • 1
Maxim Kholyavkin
  • 4,463
  • 2
  • 37
  • 82
  • 1
    [No, `@user.pledges.build` is correct and `@user.build_pledges` is wrong.](http://guides.rubyonrails.org/association_basics.html#methods-added-by-has-many) – Mischa Oct 21 '15 at 12:15
  • 20
    For single resources (has_one), for example if users had only one pledge `@user.build_pledge` is the only way to make it work. – Sia Feb 05 '16 at 20:51
  • Thanks.. Your answer helped me :), for has_one this is the way we should build – Nidhin S G Apr 06 '16 at 06:30
  • @Sia thanks so much. Do you know why this is? It seems kinda arbitrary that the association would affect such a method. – stevec Aug 19 '20 at 15:31
2

You can't call

@user.pledges.build

as below line will only create a instance of User, but not save it to database.

@user = User.new

2) Why you have pledge_id in users table, as user has_many pledges, You can't store one pledge_id in users table 3) There should be only one submit button which will the form and pledges values will be sent as nested_attributes

EDIT

class Pledge < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user

end

class User < ActiveRecord::Base
   has_many :pledges
   accepts_nested_attributes_for :pledges
   attr_accessor :pledges
end

Controller, Now this should work

def new
   @user = User.new
   @user.pledges.build
end

def create
  @user = User.new(user_params)
  respond_to do |format|
    if @user.save
      format.html { redirect_to @user, notice: 'User was successfully created.' }
    else
      format.html { render action: 'new' }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

def user_params
  params.require(:user).permit(:name, etc..., pledges_attributes:[:amount, etc..])
end    

new.erb.html

<%= form_for @user do |f| %>
  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :email %><br>
    <%= f.text_field :email %>
  </div>
  <%= f.fields_for :pledge do |builder| %>
     <%= builder.label :amount %>
     <%= builder.text_field :amount %>
  <% end %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>  
Sonalkumar sute
  • 2,565
  • 2
  • 17
  • 27
  • ok. That makes sense. I took out `@users.pledges.build` of the new method and put it under `@user = User.create(pledge_params)` in the create method. So user is saving, but I still have the same error message. Also, I can't get the pledge attributes to save. – K Waters Mar 18 '15 at 18:39
  • I'm still getting the same error message `undefined method `build' for nil:NilClass rails`. And :pledge is not saving. – K Waters Mar 18 '15 at 20:54
  • Have you removed pledge_id from users table – Sonalkumar sute Mar 18 '15 at 21:18
  • If you still face the issue, try build of pledges in create method after, `@user.save` – Sonalkumar sute Mar 18 '15 at 21:19
  • I've tried @user.save and removing pledge_id. I think it has something to do with active record or my view. pledges is still nil and build doesn't work. – K Waters Mar 18 '15 at 22:38
  • Have you tried my all the code, for view controller and all? – Sonalkumar sute Mar 19 '15 at 06:14