1

I'm trying to add a nested attributes to my signup form (generated by devise), but it didn't work.

To give a brief explanation: A user has many locations, and each location has a label name (home,eg.) and an address.

What I wanted to do here is to allow new user to register their location(nested attributes) in the signup form. In other words, to create a new location, which is associated with the new user.

*I have already set up strong params and controllers, by referring to stackoverflow threads and other sources.

Here's my codes:

User Model

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :validatable

  has_many :locations, dependent: :destroy

  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :email, presence: true

  accepts_nested_attributes_for :locations
end

Location Model

class Location < ApplicationRecord
  belongs_to :user

  validates :label, presence: true
  validates :address, presence: true

  geocoded_by :address
  after_validation :geocode, if: :will_save_change_to_address?

end

My Signup Form

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <div class="form-inputs">
..........
<%= f.simple_fields_for :location do |p| %>
  <%= p.input :address %>
  <%= p.input :label, collection: ['Home', 'Work'] %>
<% end %>
<%= f.button :submit, "Sign up", class: "btn btn-long" %>
  </div>
<% end %>

Registration Controllers (Devise)

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]

  def new
    build_resource({})
    self.resource.locations.build
    respond_with self.resource
  end
  
  protected

  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :first_name, :last_name, :password, :photo, locations_attributes: [:label, :address]])
  end
 end

Application Controller

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :first_name, :last_name, :password, :photo, locations_attributes: [:label, :address]])
  end
 end

DB Schema

 ActiveRecord::Schema.define(version: 2019_08_30_001623) do
 
 create_table "locations", force: :cascade do |t|
  t.string "label"
  t.text "address"
  t.float "latitude"
  t.bigint "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.float "longitude"
  t.index ["user_id"], name: "index_locations_on_user_id"
  end
  
 create_table "users", force: :cascade do |t|
  t.string "email", default: "", null: false
  t.string "encrypted_password", default: "", null: false
  t.string "reset_password_token"
  t.datetime "reset_password_sent_at"
  t.datetime "remember_created_at"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.string "first_name"
  t.string "last_name"
  t.boolean "admin"
  t.text "preference", default: "no preference"
  t.integer "default_location"
  t.integer "radius"
  t.index ["email"], name: "index_users_on_email", unique: true
  t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

Please let me know if you have any additional question or if you need anymore info.

Appreciate all your helps

hans1125
  • 357
  • 8
  • 15
  • Hey @gn2463, can you tell us what kind of errors you're getting? Also, check this out: https://stackoverflow.com/questions/57630480/rails-devise-create-user-and-update-associated-record/57666142#57666142 – Violeta Sep 05 '19 at 09:42
  • thank you @Violeta, I don't get any error message, but the address I entered in the signup form isn't saved to user. When I tried to put a raised earlier this afternoon, my address input did showed up in the params, but in the end it wasn't saved... Now, I tried to put a raise to check again, in both controllers and view, but neither work ... – hans1125 Sep 05 '19 at 16:44
  • 1
    Hey!! It seems that you're spelling it wrong here: `<%= f.simple_fields_for :location do |p| %>`... It should be `simple_fields_for :locations` – Alexandre Wiechers Vaz Sep 05 '19 at 19:51
  • @AlexandreWiechersVaz It worked now!! Previously the simple field didn't show up in the form, when i used ':locations'... probably there are mistake somewhere else.. Thank you!! – hans1125 Sep 06 '19 at 01:39

0 Answers0