0

I have two models ; User and Record. I would like to create automatically a new Record when creating a new User. The new Record must have an attribute which is the id of the newly created User.

I have read about using link_to, to pass a parameter but I deem this is not what I need. I'd like the code to be in the User Controller in the create action.

So I wrote this code in my controller :

  def create
    @user = User.new(user_params)

    @record = Record.new(:user_id=>@user.id)
    @record.save

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
      format.js
    end
  end

To check if it could work I wrote this instead of what is in the previous code. And it works I have a new record with an id for the user of 1

    @Record = Record.new(:user_id=>"1")
    @Record.save

How can I get instead of 1 the id of the User that is created ?

I tried several options :

params[:id]
User.find(params[:id])
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
GDMN
  • 184
  • 2
  • 17
  • this is not gonna working and defenitely not Rails-Way. – Tim Kretschmer Aug 20 '15 at 10:28
  • why do you want the code in the controller? If you don't mind moving it to the model you could do it in a before create callback in the user model. – j-dexx Aug 20 '15 at 10:28
  • I thought it was easier but I am here to learn. What shall I do in my model exactly ? I must write a method and call it before creating a new User ? – GDMN Aug 20 '15 at 10:31
  • See this answer for how to do it within a callback: http://stackoverflow.com/questions/3808782/rails-best-practice-how-to-create-dependent-has-one-relations – RichardAE Aug 20 '15 at 10:33
  • This is much better practice than having the code in the controller. – RichardAE Aug 20 '15 at 10:33

4 Answers4

1

Try below code -

 @user = User.new(user_params)
 @user.build_record # if you have has_one association in user model
 @user.records.build # if you have `has_many` association in user model

 @user.save

So your controller code should be -

def create
    @user = User.new(user_params)
    @user.build_record

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
      format.js
    end
  end
Vishnu Atrai
  • 2,370
  • 22
  • 24
  • Shall I do this in my controller ? And is that `@user.save` or `@record.save` at the end of your code ? When is my record saved ? Thanks for your answer – GDMN Aug 20 '15 at 10:34
  • Your answer works but this creates an empty record. How can I pass attribute to that new Record ? – GDMN Aug 20 '15 at 11:58
  • Like - ` @user.build_record( { name: user_params[:name]} )`. If you paste your controller `user_params` that will help to diagnose. – Vishnu Atrai Aug 20 '15 at 12:59
  • That does not fully works when I require the id to show it on the index page nothing appears. Instead I have a blank line. – GDMN Aug 20 '15 at 15:37
  • I eventually found a solution. Thank you for your help anyway – GDMN Aug 21 '15 at 08:47
0
class User
  has_many :records, autosave: true

  after_initialize {
    # this is automatically creating a new record element
    # and save its association, but only if its a new record (user)
    records.build if self.new_record?
  }
end

#in your controller
def create
   @user = User.new(user_params)
      respond_to do |format|
    if @user.save
      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render :show, status: :created, location: @user }
    else
      format.html { render :new }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
    format.js
  end
end
Tim Kretschmer
  • 2,272
  • 1
  • 22
  • 35
0

I eventually found a solution that works well. This is the code I use in my controller so that creating a User automatically create a Record with the id of the User.

I have to precise that I have for these two models the following relations:

In the user model : has_one :record

In the record model : belongs_to :user

  def create
    @user = User.new(user_params)


    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
        @record = Record.create(user: @user)
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

That is all it takes.

GDMN
  • 184
  • 2
  • 17
0

I don't think that the code in @GDMN's answer will work.

As soon as the user record is saved, it would either redirect if the request is of type html or it would render something in case of a json request. This line @record = Record.create(user: @user) would execute for request types other than html and json and never otherwise. You could rather use the below code copied from @Vishnu's answer

@user = User.new(user_params)
@user.build_record

respond_to do |format|
  if @user.save
    format.html { redirect_to @user, notice: 'User was successfully created.' }
    format.json { render :show, status: :created, location: @user }
  else
    format.html { render :new }
    format.json { render json: @user.errors, status: :unprocessable_entity }
  end
  format.js
end
Pramod Solanky
  • 1,690
  • 15
  • 17