At first glance it would seem this question has been answered before, but not on my case (most are related to mass assignment issues and/or mongoid.) I have not been able to find an answer even though there are plenty somewhat related questions here.
So basically I'm using the devise gem for user authentication on a ruby on rails application and I want to add a nested address model to the user model. I'm also using simple_form to generate the form views.
I have a user model:
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
has_one :address
accepts_nested_attributes_for :address, :allow_destroy => true
end
This is the address model:
class Address < ActiveRecord::Base
belongs_to :country
belongs_to :state
belongs_to :user
attr_accessible :street1, :street2, :country_id, :state_id, :city, :postalCode
end
This is the Users controller, which I overrode in order to add a show action to display user profile.
class Users::RegistrationsController < Devise::RegistrationsController
def new
resource = build_resource({})
resource.build_address
respond_with resource
end
# POST /resource
def create
resource = build_resource(params[:user])
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
def show
@user = User.find(params[:id])
#Add to view count if not viewing own user profile
if @user != current_user
@user.views += 1
@user.save
end
@vehicles = Vehicle.where(:user_id => @user)
respond_to do |format|
format.html # show.html.erb
format.json { render json: @user }
end
end
end
This is the view for creating new users:
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name) ) do |f| %>
<fieldset>
<%= f.input :username, :required => false, :autofocus => true, placeholder: 'Pick a username' %>
<%= f.input :email, :required => false, placeholder: 'Your email' %>
<%= f.input :password, :required => false, placeholder: 'Create a password' %>
<%= f.input :password_confirmation, :required => false, placeholder: 'Confirm your password' %>
<%= f.association :roles, :as => :check_boxes, :label => "", :required => false %>
<%= f.simple_fields_for :address do |a| %>
<%= a.input :street1 %>
<%= a.input :street2 %>
<%= a.association :country %>
<%= a.association :state %>
<%= a.input :city %>
<%= a.input :postalCode %>
<% end %>
<%= f.button :submit, 'Sign up for free', :class => 'btn btn-success btn-large' %>
</fieldset>
<% end %>
So the error upon creating a new user is this: Address user can't be blank
Basically the foreign key user_id is not being set for address.
I was hoping somebody can shed a little light on this issue.
I was able to solve this in my application, but I am using strong parameters. However the solution should still be applicable in your case.
Instead of overriding all of the methods in the RegistrationsController
I just overrode build_resource
to pass in the correct parameters needed.
def build_resource(params)
super(resource_params)
end
def resource_params
params.require(:user).permit(:email, :password, tickets_attributes: [ :description ] )
end
I also have the inverse_of
on my User
and Ticket
models, Like this:
user.rb
has_many :tickets, inverse_of: :user
ticket.rb
belongs_to :user, inverse_of :tickets
Forgot to add user_id to address migration. Rails expected it when adding belongs_to :user to the address model.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.