Gurmukh Singh
Gurmukh Singh

Reputation: 2017

rails form outputs a score

I have a form which takes in loads of data here is an example of the form:

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

<form>

<div class="form-group">
    <label for="Email">Small bio about yourself</label>
    <%= f.text_area :bio, :class => "form-control", :id => "Email", :rows => "3",
      :placeholder => "bio here"%>
  </div>

<div class="field">
    <%= f.fields_for :portfolios do |portfolio| %>
      <%= render partial: 'partials/portfolio_fields', :f => portfolio  %>
    <% end %>
    <div class="links">
      <%= link_to_add_association 'add image', f, :portfolios %>
    </div>
  </div>

</form>
<% end %>

the profile(scaffolded) belongs to a user created by devise. What I'm trying to do is for example if the user fills his bio, he gets a score (+2 points) and for each portfolio he adds he gets more (+5 points) and at the end of the form the score is calculated.

something like this

if bio.empty?
 score = 3
else
 score = 0
end

Upvotes: 0

Views: 168

Answers (1)

Dharam Gollapudi
Dharam Gollapudi

Reputation: 6438

If you want to display the score to the user as he fills in the info (ex: bio, portfolios) etc, then you need to look at implementing in the client side using javascript.

But if you want to save it to the profiles table upon form submission and display that info later to the user, then you can implement it through callbacks on the Profile model as follows:

class Profile < ActiveRecord::Base
  belongs_to :user

  before_save :assign_score

  protected
  def assign_score
    score = self.score || 0
    score += 3 if self.changes.include?(:bio) and self.bio.present?
    score += 5 if self.portfolios.present?

    self.score = score
  end
end

The problem with this approach, is that every time you update the profile record, you need to make sure that you are not double calculating by storing other info like bio_calculated, etc. Otherwise, you keep adding the score for bio and portfolios etc.

Or if you want to just display the score, which is computed dynamically, you could define a custom method in your Profile model as follows:

class Profile < ActiveRecord::Base
  belongs_to :user

  def score
   score = 0
   score += 3 if self.bio.present?
   score += 5 * self.portfolios.count
   score # this last line is optional, as ruby automatically returns the last evaluated value, but just added for explicity
  end
end

Upvotes: 1

Related Questions