Reputation: 197
I'm getting the error "wrong number of arguments (2 for 0) from 'build_profile' function in user.rb while trying to add a profile to a user using the one to one relationship.
Models
class User < ActiveRecored::Base
has_one :profile, dependent: :destroy
after_create :build_profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password, :password_confirmation, :profile_attributes
def build_profile
Profile.create(user: self)
end
end
class Profile < ActiveRecord::Base
attr_accessible :name. :address, :age
belongs_to :user
validates :name, presence: true, length: { maximum: 50 }
validates :address, :age, presence: true
end
class UsersController < ApplicationController
def new
@user = User.new
@profile = self.build_profile
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
flash[:success] = "welcome, Thanks for Signing up"
redirect_to @user
else
render 'new'
end
end
end
class ProfilesController < ApplicationController
def edit
@profile = Profile.find(params[:id])
end
def show
@user.profile = User.find(params[:id]).profile
end
def destroy
end
end
I get this error when a user tries to sign up , below is the sign up form
<h1> Sign Up </h1>
<div class="span6 offset3">
<%= form_for (setup_user(@user)) do |f| %>
<%= f.fields_for :profile do |ff| %>
<p>
<%= ff.label :name %>
<%= ff.text_field :name %>
</p>
<% end %>
<p>
<%= f.label :email %>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %>
<%= f.pasword_field :password %>
</p>
<p>
<%= f.label :password_conformation, "Confirm Password" %>
<%= f.password_field :password_confirmation%>
</p>
<%= f.submit "create my account", class: "btn btn-large btn-primary" %>
<% end %>
Thanks
Server Log Output for posting the user new form
Started POST "/users" for 127.0.0.1 at 2014-10-13 10:01:42 -0400
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"G£ô", "authenticity_token"=>"7PQwoH4VGDE2kyHqjkv4PegFz/A
KYGYXRFtQpn9UKko=", "user"=>{"profile_attributes"=>{"name"=>"Example Test"}, "em
ail"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[F
ILTERED]"}, "commit"=>"Create my account"}
(0.0ms) BEGIN
User Exists (25.0ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'ex
[email protected]' LIMIT 1
(0.0ms) ROLLBACK
Rendered users/new.html.erb within layouts/application (4.0ms)
User Load (1.0ms) SELECT `users`.* FROM `users` WHERE `users`.`remember_token
` IS NULL LIMIT 1
Rendered layouts/_header.html.erb (3.0ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 330ms (Views: 93.0ms | ActiveRecord: 26.0ms)
Upvotes: 0
Views: 450
Reputation: 197
I have been able to finally found a solution to both queries i had; the latter resulting from attempted solution from my first question.
A. ArgumentError in UsersController#create; Wrong number of arguments (2 for 0)
B. Form_for taking in values and not posting to database.
I am posting my solution here for future references for any one run into either problems with their codes.
Andrew, Thanks for referring me to the guide, it was an educational read.
Juanpastas, Thanks. You helped solved both queries, though i ended up using Profile.create(user_id: self.id)
instead of Profile.create(user: self)
due to trouble with mass assignment of protected values.
Your comment requesting the server log output made me scrutinize the log and noticed that it was rolling back the parameters instead of saving them to the database.
Through research and other post on here such as, how to find the cause of ActiveRecord ROLLBACK (Serge Seletskyy's answer), and Max Wong's answer in Why does my rails rollback when I try to user.save? , I learned it might be due to failing validations
Using User.save!
as the if condition in my User's create function helped see that some other attributes and the line validates :address, :age, :sex, presence: true
in the profile model was making the callback function to fail validation as they can't be blank and return false, causing the rollback by the server, but commenting out the line, #validates :address, :age, :sex, presence: true
, solved it.
Upvotes: 0
Reputation: 203
Since you are already defining a relationship for these two models (user has_one :profile), the build_profile is already defined for you. No need to do so in your model. take a look at http://edgeguides.rubyonrails.org/association_basics.html for more details.
Upvotes: 0
Reputation: 21795
It's because build_profile
is a method already defined by Rails.
Try changing the name:
after_create :build_default_profile
def build_default_profile
Profile.create(user: self)
end
Upvotes: 1