2
votes

I have a has_one association and accepts_nested_attributes for between a User and his profile. Although all parameters are being passed according to logs, I keep running into unpermitted parameter profile.

User model

class User < ActiveRecord::Base
  searchkick

  validates_presence_of :first_name, :last_name, :phone_number
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i

  validates :email, presence: true,
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }

  has_one  :profile, dependent: :destroy

  accepts_nested_attributes_for :profile

  validates_associated :profile

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def name
    [first_name, last_name].compact.join(' ')
  end 
end

Profile model

class Profile < ActiveRecord::Base
  belongs_to :user

  mount_uploader :identification_recto, FileUploader
  mount_uploader :identification_verso, FileUploader

  mount_uploader :proof_of_income_1, FileUploader
  mount_uploader :proof_of_income_2, FileUploader
  mount_uploader :proof_of_income_3, FileUploader

  validates_presence_of :user_id  
end

User controller

class Teller::UsersController < TellerController

  def new
    @user = User.new
    @user.build_profile           
  end

  def create
    @user = User.new create_params
    @user.enroller_id = current_user.id
    # @profile.user_id = @user.id    
    save_user or render 'new'    
  end
  private

   def load_user
      @user ||= user_scope.find(params[:id])
   end

   def user_scope
      User.where(nil)
   end

   def save_user
      if @user.save
        flash[:success] = "C'est fait!"      
        redirect_to teller_root_path
      end      
   end

   def create_params
      params.require(:user).permit(:first_name, :last_name,
                                   :email, :password, :phone_number, :succ, :teller,
                                   profile_attributes: [:identification_recto,
                                                        :identification_verso,
                                                        :proof_of_income_1,
                                                        :proof_of_income_2,
                                                        :proof_of_income_3])           
   end
end

Form

<%= render 'shared/error_messages', object: f.object %>

<%= f.text_field :first_name, placeholder: "Prénoms", class: "form-control" %> <br />

<%= f.text_field :last_name, placeholder: "Nom", class: "form-control" %> <br />

<%= f.text_field :email, placeholder: "email", class: "form-control" %> <br />

<%= f.password_field :password, placeholder: "Mot de passe - 8 characteres min", class: "form-control" %> <br />

<%= f.text_field :phone_number, placeholder: "Numero de téléphone", class: "form-control" %> <br />

 <span class="form-control">
    <%= f.check_box :succ %> Succursale
 </span> <br />

 <span class="form-control">
    <%= f.check_box :teller %> Agent
 </span> <br />

 <div class="panel panel-default">
  <%= f.fields_for [:profile, @user.build_profile] do |builder| %>
    <%= render 'shared/profile_fields', f: builder %>
  <% end %>
</div>

Profile fields partial

<div class="panel-heading">
        <h5 class="text-uppercase">Profile</h5>
</div>
<fieldset class="panel-body">
    <h4 class="text-center">
        Identification
    </h4>

    <%= f.file_field :identification_recto, placeholder: "Upload", class: "form-control" %>
    <br />

    <%= f.file_field :identification_verso, placeholder: "Upload", class: "form-control" %>

    <h4 class="text-center">
        Sources de revenus
    </h4>

    <%= f.file_field :proof_of_income_1, class: "form-control" %>
    <br />
    <%= f.file_field :proof_of_income_2, class: "form-control" %>
    <br />
    <%= f.file_field :proof_of_income_3, class: "form-control" %>
    <br />
</fieldset>

Log

Parameters: {"utf8"=>"✓", "authenticity_token"=>"TniskJATOw8LLh9jUSk28sV4RfKnwUH9ngExOE4TPtPSf/u5cYF/7b7WEu3mKfvgMFDD4hk+78u6tDkr/IEEuw==", "user"=>{"first_name"=>"Aziz", "last_name"=>"Test", "email"=>"[email protected]", "password"=>"[FILTERED]", "phone_number"=>"+1 416 388 94 49", "succ"=>"0", "teller"=>"0", "profile"=>{"identification_recto"=>#<ActionDispatch::Http::UploadedFile:0x007f8640a10c98 @tempfile=#<Tempfile:/var/folders/8x/x82yrjys3_n11t6ktj4mx8xr0000gn/T/RackMultipart20160714-57689-iuz82p.png>, @original_filename="headline-lockup.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[profile][identification_recto]\"; filename=\"headline-lockup.png\"\r\nContent-Type: image/png\r\n">, "identification_verso"=>#<ActionDispatch::Http::UploadedFile:0x007f8640a10c48 @tempfile=#<Tempfile:/var/folders/8x/x82yrjys3_n11t6ktj4mx8xr0000gn/T/RackMultipart20160714-57689-kzsycl.png>, @original_filename="headline-lockup.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[profile][identification_verso]\"; filename=\"headline-lockup.png\"\r\nContent-Type: image/png\r\n">, "proof_of_income_1"=>#<ActionDispatch::Http::UploadedFile:0x007f8640a10bf8 @tempfile=#<Tempfile:/var/folders/8x/x82yrjys3_n11t6ktj4mx8xr0000gn/T/RackMultipart20160714-57689-1navy8v.png>, @original_filename="headline-lockup.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[profile][proof_of_income_1]\"; filename=\"headline-lockup.png\"\r\nContent-Type: image/png\r\n">, "proof_of_income_2"=>#<ActionDispatch::Http::UploadedFile:0x007f8640a10ba8 @tempfile=#<Tempfile:/var/folders/8x/x82yrjys3_n11t6ktj4mx8xr0000gn/T/RackMultipart20160714-57689-1cfuegj.png>, @original_filename="headline-lockup.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"user[profile][proof_of_income_2]\"; filename=\"headline-lockup.png\"\r\nContent-Type: image/png\r\n">}}, "commit"=>"Je valide"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
Unpermitted parameter: profile
   (0.1ms)  BEGIN
  User Exists (0.5ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1
  SQL (0.3ms)  INSERT INTO "users" ("first_name", "last_name", "email", "encrypted_password", "phone_number", "enroller_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["first_name", "Aziz"], ["last_name", "Test"], ["email", "[email protected]"], ["encrypted_password", "$2a$11$VR7dPZ7cJkZQP1Bxm/2fXO.2BtUHJbLd2Rp.9vjBQQEr5AsZt5fF."], ["phone_number", "+221 76 388 94 49"], ["enroller_id", 1], ["created_at", "2016-07-14 08:53:00.023114"], ["updated_at", "2016-07-14 08:53:00.023114"]]

All inputs welcome. Thank you for your help

Note: I have had a look at this has_one nested attributes not saving to no avail

Thanks !

1
what is the paremeter structure you are getting from server ?Sabyasachi Ghosh
Try changing <%= f.fields_for [:profile, @user.build_profile] do |builder| %> to <%= f.fields_for :profile do |builder| %>Pavan
@Pavan: that seems to be the right way to go, i get the following error 'Profile user can't be blank'. however how do i go about setting '@profile.user_id' in controller since it can't be mentioned without setting it to nilGhost
@SabyasachiGhosh: i posted w/ the question. it's the last bit of code :)Ghost
In that case the structure is wrong. the profile attributes should come like profile_attributes @GhostSabyasachi Ghosh

1 Answers

0
votes

You should do this

<%= f.fields_for :profile do |builder| %>

and in controller

def new
  @user = User.new
  @profile = @user.build_profile
end

I hope this will fix your problem. Thanks