Adt
Adt

Reputation: 495

Fill form with two values

I have user/registrations/new.html.haml

- title 'User Registration'

.vcentered  .signup-box
  - if @user.authorizations.any?    %h1 We just need a little more information...
  - else    %h1 We just need a little bit of information...

  = form_for @user, url: user_registration_path, html: { class: 'new-user form-default' } do |f|
   - if @user.name.blank?
    = f.text_field :name, class: class_with_errors(@user, :name),
                          title: title_with_errors(@user, :name),
                          placeholder: 'Full Name'

   - if @user.email.blank? || @user.errors.any?
    = f.text_field :email, class: class_with_errors(@user, :email),
                           title: title_with_errors(@user, :email),
                           placeholder: 'Email'

   - if @user.authorizations.empty?
    = f.password_field :password, class: class_with_errors(@user, :password),
                                  title: title_with_errors(@user, :password),
                                  placeholder: 'Password'

   = f.fields_for :profile do |p|
    = p.hidden_field :username, value: () 
    = p.text_field :place, class: class_with_errors(@user.profile, :place),
                           title: title_with_errors(@user.profile, :place),
                           id: 'profile-place',
                           placeholder: 'Type in your closest city...'
    = p.hidden_field :city_id, id: 'profile_city_id'
    .tip
     E.G. "New York, New York, United States" or "Barcelona, Cataluña, Spain"

    .note
     Ps - We need this information to show you data relevant to your location.
     We don't share it with anyone. If you cannot find your city, please type
     the largest city closest to you.

   = f.submit 'Sign up', class: 'submit'

Due to some association issue, I want to fill the value of

 p.hidden_field :username, value: () 

with name and id.

For example if user fill name as 'Name Surname' and user id is '55' then username should be NameSurname55.

Please suggest code. Thanks in advance

My usercontroller looks like:

class Users::RegistrationsController < Devise::RegistrationsController
  layout 'land'
  #before_action :set_username

  def create
    params[:user][:profile_attributes].delete(:place)

    super do |resource|
      UserMailer.welcome(resource).deliver

      aroundyoga_user = User.find_by(email: '[email protected]')
      resource.follow!(aroundyoga_user) && aroundyoga_user.follow!(resource)

      RegistrationWorker.perform_async(resource.id)
    end
  end

  protected

    def after_sign_up_path_for(resource)
      welcome_path
    end

end

Upvotes: 0

Views: 59

Answers (4)

Yan Foto
Yan Foto

Reputation: 11378

I would avoid revealing IDs to the public, but If you insist:

Creating an object from params in the controller is as easy as writing

mo = MyObject.new params[my_object]

in your controller. If you need to change some attributes you would just do the following:

mo.name = mo.name + mo.id

remember that in both cases you have to call save to persist changes.

The biggest difficulty in your case is that if the user hasn't been persisted yet (i.e. it's a new object created using User.new) it hasn't been assigned an ID yet. But there's also an answer for that here

The easiest way might be:

class Profile < ActiveRecord::Base
  after_create :update_name

  def update_name
    name = name + id
    save
  end
end

Upvotes: 1

glyuck
glyuck

Reputation: 3397

Your :username input is hidden, so I assume user should not be able to edit username. Then you better remove this field from form at all and do all logic on server-side:

def create
  params[:user][:profile_attributes].delete(:place)

  super do |resource|
    # Next 2 lines
    resource.profile.username = resource.name.gsub(/\s+/, "") + resource.id.to_s
    resource.profile.save

    UserMailer.welcome(resource).deliver

    aroundyoga_user = User.find_by(email: '[email protected]')
    resource.follow!(aroundyoga_user) && aroundyoga_user.follow!(resource)

    RegistrationWorker.perform_async(resource.id)
  end
end

Edit: updated code according to information you provided. @pkrawat1 solution is better.

Upvotes: 2

xiongbo027
xiongbo027

Reputation: 96

looks like you have used accept_nested_attributes in background.

so may be you can use callback in profile model like:

after_create: update_profile_username

def update_profile_username
  username = user.name + user.id
  save
end

Upvotes: 1

pkrawat1
pkrawat1

Reputation: 681

Add this in your profile model

before_create :generate_username

def generate_username
  self.username = self.user.name.underscore + self.user.id.to_s
end

Upvotes: 2

Related Questions