0

Im new to RoR and I have a hard time in experimenting some syntax.

I don't know how to add two inputted numbers coming from here:

<div class="field">
<%= f.label :point1 %><br>
<%= f.number_field :point1 %>

</div>
<div class="field">
<%= f.label :point2 %><br>
<%= f.number_field :point2 %>

</div>

I also want to save the numbers to database including their sum. I already searched it from the Internet but I'm not satisfied with the results.

I hope someone will help me. Thank you.

by the way, I know how to save the two inputted numbers in database except the sum.

these are my codesss!

player.rb

 class Player < ActiveRecord::Base
    before_save :add_point1_and_point2
private
def add_point1_and_point2
  self.point3 = self.point1 + self.point2
  self.save
end
end

_form.html.erb

<%= form_for(@player) do |f| %>
  <% if @player.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@player.errors.count, "error") %> prohibited this player from being saved:</h2>

      <ul>
      <% @player.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

<% sum = 0 %>
  <div class="field">
    <%= f.label :point1 %><br>
    <%= f.number_field :point1 %>

  </div>
  <div class="field">
    <%= f.label :point2 %><br>
    <%= f.number_field :point2 %>

  </div>


  </div>
  <div class="actions">
    <%= f.submit %>

  </div>
<% end %>

players_controller.rb

class PlayersController < ApplicationController

  before_action :set_player, only: [:show, :edit, :update, :destroy]

  # GET /players
  # GET /players.json
  def index
    @players = Player.all
  end

  # GET /players/1
  # GET /players/1.json
  def show
  end

  # GET /players/new
  def new
    @player = Player.new
    end




  # GET /players/1/edit
  def edit
  end

  # POST /players
  # POST /players.json
  def create

   # @player = Player.new(sum_num :point3)

    @player = Player.new(player_params)

    respond_to do |format|
      if @player.save

        format.html { redirect_to @player, notice: 'Player was successfully created.' }
        format.json { render :show, status: :created, location: @player }
      else
        format.html { render :new }
        format.json { render json: @player.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /players/1
  # PATCH/PUT /players/1.json
  def update
    respond_to do |format|
      if @player.update(player_params)
        format.html { redirect_to @player, notice: 'Player was successfully updated.' }
        format.json { render :show, status: :ok, location: @player }
      else
        format.html { render :edit }
        format.json { render json: @player.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /players/1
  # DELETE /players/1.json
  def destroy
    @player.destroy
    respond_to do |format|
      format.html { redirect_to players_url, notice: 'Player was successfully destroyed.' }
      format.json { head :no_content }
    end
  end



  private
    # Use callbacks to share common setup or constraints between actions.
    def set_player
      @player = Player.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def player_params
      params.require(:player).permit(:point1, :point2)
    end

end
ana
  • 603
  • 6
  • 17

3 Answers3

2

Check ActiveRecord Callbacks. Look for before_save and after_save

In your model, you should have code similar to this

before_save :add_point1_and_point2
private
def add_point1_and_point2
  sum_value = self.point1 + self.point2
  self.assign_attributes(sum_column: sum_value)
end
gkolan
  • 1,571
  • 2
  • 20
  • 37
  • ana, you should add all the code in the question itself. You ask the question, community answers! :) – gkolan Jan 13 '15 at 03:18
2

Well there are couple of ways do that. But you can't use self.save in before_save or after_save here as save will call these before_save and after_save again hence stack level too deep. use update_column instead it will not trigger any callbacks

after_save :add_point1_and_point2
def add_point1_and_point2
  update_column(:point3, point1 + point2)
end
Abubakar
  • 1,022
  • 10
  • 20
  • another error appeared : "cannot update on a new record object" on "update_column(point3, point1 + point2)" – ana Jan 13 '15 at 05:28
  • ActiveRecord::ActiveRecordError in PlayersController#create – ana Jan 13 '15 at 05:30
  • Change 'before_save' to 'after_save' – Abubakar Jan 13 '15 at 05:34
  • error again.. "Mysql2::Error: Unknown column 'players.2' in 'field list': UPDATE `players` SET `players`.`2` = 2 WHERE `players`.`id` = 22" – ana Jan 13 '15 at 05:38
2

1st thing: you are missing your result column may be column 'sum'

#this will add a new column sum to the players.

rails g migration add_sum_to_players sum:integer 
rake db:migrate

next try this in your model file:

 #player.rb
class Player < ActiveRecord::Base 

before_save :calculate_sum

private 
  def calculate_sum
    result = point1 + point2 
    self.assign_attributes(sum: result)
  end
end

As we are just assigning attribute (sum as the + of point1 and point2), so this not going to save it. this is just assigning, as we are triggering this before_save. so, when the save will be triggered this sum value is going to be saved automatically. :)

Ajay
  • 4,199
  • 4
  • 27
  • 47
  • Please do consider accepting this if this has fixed your issue. the complete code you can find here : https://gist.github.com/AjayROR/b051edaf31d4f827d71e – Ajay Jan 13 '15 at 05:56