Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the same form for creating and editing in ruby on rails

I am new to ruby. I have the same form but i need it to perform creation/updation as and when required. The problem i have now is that whenever i call edit instead of editing the details of an existing user, i am getting a new user with the edited details. To put it simply, i think whenever i perform edit, the create method is being called.

So is there any way to use single form for both new and edit instead of using separate forms.

The following code is for editing user details:

         <%= link_to 'Home', root_path %>
        <h2>Edit user</h2>
        <%= form_for :user, url: user_index_path do |f| %>
          <p>
            <%= f.label :name %><br>
            <%= f.text_field :name %>
          </p>

          <p>
            <%= f.label :address %><br>
            <%= f.text_area :address %>
          </p>
         <p>
            <%= f.label :email %><br>
            <%= f.text_field :email %>
          </p> 
         <p>
            <%= f.label :phone %><br>
            <%= f.text_field :phone %>
          </p>
          <p>
            <%= f.label :state %><br>
            <%= f.text_field :state %>
          </p>
          <p>
            <%= f.label :country %> 
            <%= f.collection_select(:country, Country.all, :name, :name) %>
          </p>
          <p>
            <%= f.submit %>
          </p>
        <% end %>

The following code is for creating user:

        <%= link_to 'Home', root_path %>
    <h2>Create new user</h2>
    <%= form_for :user, url: user_index_path do |f| %>
      <p>
        <%= f.label :name %><br>
        <%= f.text_field :name %>
      </p>

      <p>
        <%= f.label :address %><br>
        <%= f.text_area :address %>
      </p>
     <p>
        <%= f.label :email %><br>
        <%= f.text_field :email %>
      </p> 
     <p>
        <%= f.label :phone %><br>
        <%= f.text_field :phone %>
      </p>
      <p>
        <%= f.label :state %><br>
        <%= f.text_field :state %>
      </p>
      <p>
        <%= f.label :country %> 
        <%= f.collection_select(:country, Country.all, :name, :name) %>
      </p>
      <p>
        <%= f.submit %>
      </p>
    <% end %>

And this is my controller:

      class UserController < ApplicationController
    def index
        @users = User.all

    end

    def show
    @user = User.find(params[:id])
  end

    def new
        @user = User.new
    end


    def create
    @user = User.new(user_params)
        if @user.save
            redirect_to @user
        else
            render 'new'
        end 
    end

  def edit

    @user = User.find(params[:id])


  end

    def update
    #@user = User.find(params[:id])
        if @user.update(user_params)
        redirect_to @user
    else
      render 'edit'
    end
    end

    def destroy
    @user = User.find(params[:id])
    @user.destroy
      redirect_to user_index_path
  end

    private
    def user_params
        params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
    end

end

Since i am new to ruby, i did not get the exact details of how http requests function in ruby.

like image 496
Akshay Avatar asked Jun 01 '15 04:06

Akshay


1 Answers

users/_form.html.erb

  <%= link_to 'Home', root_path %>
  <%= form_for @user do |f| %>
  <p>
  <%= f.label :name %><br>
  <%= f.text_field :name %>
  </p>

  <p>
  <%= f.label :address %><br>
  <%= f.text_area :address %>
  </p>
  <p>
  <%= f.label :email %><br>
  <%= f.text_field :email %>
  </p> 
  <p>
  <%= f.label :phone %><br>
  <%= f.text_field :phone %>
  </p>
  <p>
  <%= f.label :state %><br>
  <%= f.text_field :state %>
  </p>
  <p>
  <%= f.label :country %> 
  <%= f.collection_select(:country, Country.all, :name, :name) %>
  </p>
  <p>
  <%= f.submit %>
  </p>
  <% end %>

users/new.html.erb

<h2>Create new user</h2>
<%= render 'form' %>

users/edit.html.erb

<h2>Edit user</h2>
<%= render 'form' %>

users_controller.rb

class UsersController < ApplicationController
  before_filter :find_user, only: [:show, :edit, :update, :destroy]
  def index
    @users = User.all
  end

  def show    
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end 
  end

  def edit
  end

  def update
    if @user.update(user_params)
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    @user.destroy
    redirect_to user_index_path
  end

  private
  def user_params
    params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
  end

  def find_user
    @user = User.find(params[:id])
  end

end

When you have same view code for two or more methods, you should create a partial of same view code and render it in those methods. This is called DRY principle in ruby on rails

like image 178
Vrushali Pawar Avatar answered Oct 04 '22 00:10

Vrushali Pawar