Question

I've followed Hartl's rails tutorials to the of Chap 9 and now i'm building my own idea so i can get deep into rails.

Current issue - I've added a Bio filed to user profiles in edit and the text box appear on the Users profile but i can't figure out how to save the text added to the Bio text box. I've generated a migration called "add_bio_to_user_profile" (haven't raked yet) but i'm struggling to figure out what to add to the User.rb model. Does controller come into this to?

Migration "add_bio_to_user_profile"

   class AddBioToUserProfile < ActiveRecord::Migration
  def change
    add_column :user_profiles, :, :string
  end
end

Model/User.rb

class User < ActiveRecord::Base

  before_save { self.email = email.downcase }
  before_create :create_remember_token

  validates :name, presence: true, length: { maximum: 50 }
  #VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence:   true,
                    #format:     { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, length: { minimum: 6 }

  def User.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def User.encrypt(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

  private

    def create_remember_token
      self.remember_token = User.encrypt(User.new_remember_token)
    end
end

controllers/user_controller.rb

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy

def index
    @users = User.paginate(page: params[:page])
  end

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

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

  def new
    @user = User.new
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User destroyed."
    redirect_to users_url
  end


  def create
    @user = User.new(user_params)
      if @user.save
        sign_in @user
        flash[:success] = "Welcome to the Sample App!"
        redirect_to @user
      else
        render 'new'
      end
  end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      sign_in @user
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

    # Before filters

    def signed_in_user
      unless signed_in?
        store_location
        redirect_to signin_url, notice: "Please sign in."
      end
    end

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end
end

show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="span4">
    <section>
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>

        <div>
            <textarea rows="3"></textarea>
            </div>

  </aside>
</div>

edit.html.erb

<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for(@user) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :bio %>
      <textarea rows="3"></textarea>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>

    <%= gravatar_for @user %>
    <a href="http://gravatar.com/emails">change</a>
  </div>
</div>
Was it helpful?

Solution

Formally, you dont have to do anything. Rails magic starts here. You run the migration, restart server if you are running production env, change the name of textbox to :bio in edit html.erb

<%=f.text_field :bio%>

When this form is submitted, it automatically gets saved in the table. Additionally, you can add validation on this field in model.

In edit.html.erb, make this change

  <%= f.label :bio %>
  <%=f.text_field :bio%>

and in show.html.erb

    <%= gravatar_for @user %>
    <%= @user.name %>
  </h1>
Bio: <%= @user.bio %>

One change in controller.rb

def user_params
params.require(:user).permit(:name, :email, :bio, :password,
                                       :password_confirmation)
end

OTHER TIPS

You want to add bio field to users table I guess. Here is the migration.

class AddBioToUserProfile < ActiveRecord::Migration
  def change
    add_column :users, :bio, :string
  end
end

While you are going for a migration, only model comes to play. and in this, users is your table name and bio is the new column and string is the data-type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top