Reputation: 2017
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
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