Rails 4 - validate model is not working - ruby-on-rails

Appreciate if you help me. I have a rails project, where people can book tickets to an airplanes (not a real project, just trying to learn rails :) ).
I have two cfaffolded objects - 'seats' and 'flights', and customer can buy a seat from every flight page (seats loads as partials).
My /app/views/flights/show.html.erb looks like that:
<p>
<strong>Departure:</strong>
<%= #flight.departure %>
</p>
<p>
<strong>Destination:</strong>
<%= #flight.destination %>
</p>
<p>
<strong>Baggage allowance:</strong>
<%= #flight.baggage_allowance %>
</p>
<%= render partial: "new_seat", locals: {seat: Seat.new(flight_id: #flight.id)} %>
<%= link_to 'Edit', edit_flight_path(#flight) %> |
<%= link_to 'Back', flights_path %>
My new_seat partial /app/views/flights/_new_seat.html.erb :
<h1>New Seat</h1>
<%= form_for(seat) do |f| %>
<% if seat.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(seat.errors.count, "error") %> prohibited this seat from being saved:</h2>
<ul>
<% seat.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :flight_id %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :baggage %><br>
<%= f.text_field :baggage %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If it is important - I made new_seat partial by myself through copying it from /app/views/seats/new.html.erb
And now I need to validate baggage amount to prevent my clients grab big bags. I wrote my /app/models/seat.rb this way:
class Seat < ActiveRecord::Base
belongs_to :flight
def validate
if baggage > flight.baggage_allowance
seat.errors.add(:base, message: "You have too much baggage")
end
end
end
But it is not working - there is no errors on site when clients enters big amounts in baggage field. What am I doing wrong?

validate method is already available(its a class method that ActiveRecord provides us to implement our custom validations). You can use that method which AR provides. something like the code below
validate :check_baggage_limit
def check_baggage_limit
if baggage > self.flight.baggage_allowance
self.errors.add(:base, "You have too much baggage")
end
end

You can add your custom validations in two ways.
First is Custom method like below
class Seat < ActiveRecord::Base
belongs_to :flight
validate :baggage_limit
def baggage_limit
if baggage > flight.baggage_allowance
errors.add(:base, message: "You have too much baggage")
end
end
end
Second is Custom Validators
class BaggageValidator < ActiveModel::Validator
def validate(seat)
if seat.baggage > seat.flight.baggage_allowance
seat.errors.add(:base, message: "You have too much baggage")
end
end
end
class Seat < ActiveRecord::Base
include ActiveModel::Validations
belongs_to :flight
validates_with BaggageValidator
end
You must have misread the http://guides.rubyonrails.org/active_record_validations.html#custom-validators

Related

Create several records at once in Rails

In my app users can create a set of codes to used in marketing activities. Therefore I want a form in which a user can type the amount of codes he want to create and then the system should generate that many codes and save them to the database.
code.rb
class Code < ActiveRecord::Base
belongs_to :form
attr_accessor :amount
end
_form.html.erb
<%= form_for [:customer, #code] do |f| %>
<% if #code.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#code.errors.count, "error") %> prohibited this code from being saved:</h2>
<ul>
<% #code.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :amount %><br>
<%= f.text_field :amount %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I want to do now is to tell the controller:
take :amount
create as many SecureRandom.hex(3) as :amount specifies
save all codes to database (column for the codes in the table is named "code")
However, I totally don't know how to achieve this...

Rails undefined method * for nil:NilClass

I am having an issue and I have done some reasearch, from my research I have found that the variable that is being used is empty, however I am unsure as to why it is empty, Maybe its something obvious to someone else?
I am trying to display a nested form on a page from another controller, I am used nested resources, Which I think might be my issue, but unsure how to resolve it.
Getting the following error:
undefined method `submission' for nil:NilClass
Structure of Project
Main Folders
-Members
--Questions
--Submissions
Concept:
Question - has_many - Submissions
Submission - Belongs_to - Question
Submission Model:
class Submission < ActiveRecord::Base
belongs_to :question
belongs_to :member
end
Question Model:
class Members::Question < ActiveRecord::Base
has_many :submissions
end
Submissions Controller:
def create
#question = Members::Question.find(params[:question_id])
#submission.member_id = current_member.id
#submission = #question.submissions.create(params[:submission].permit(:content, :question_id))
*Redirect Method Here *
end
In the form I am using the following method:
<%= form_for([#question, #question.submission.build]) do |f| %>
<% if #submission.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#submission.errors.count, "error") %> prohibited this submission from being saved:</h2>
<ul>
<% #submission.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And then to display the form on the show page of the question, I am using
<%= render 'members/submissions/form' %>
Routes:
namespace :members do
resources :questions, only: [:index,:show] do
resources :submissions
end
end
Any one any ideas where I am going wrong?
Any help is appreciated.
I have solved the problem, Thank you for the suggestions, I was using the wrong variable, I was using #question, When because its nested, the correct variable is #members_question
Submissions Controller
def create
#members_question = Members::Question.find(params[:question_id])
#submission = #members_question.submissions.create(params[:submission].permit(:content, :question_id))
#submission.member_id = current_member.id
end
_form.html.erb
<%= form_for([#members_question, #members_question.submissions.build]) do |f| %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

Nested forms in rails 4 and the fields_for method

I am also having problems with nested forms and Rails 4 (this seems to be quite common unfortunately). I have events which have requirements, the models are:
class Event < ActiveRecord::Base
enum type: [:lecture, :exercise, :tutorial]
has_one :requirement, dependent: :destroy
#accepts_nested_attributes_for :requirement
end
and
class Requirement < ActiveRecord::Base
belongs_to :event
end
There is essentially a one-to-one correspondence between those two.
Now I would like to create a new event together with the associated
requirement. I am using the following form:
<div class="container">
<%= form_for(#event) do |f| %>
<% if #event.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#event.errors.count, "error") %> prohibited this event from being saved:</h2>
<ul>
<% #event.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="container">
<%= f.select :type, Event.types.map { |key, value| [key.humanize, key] }%>
<%= f.text_field :number, placeholder: "1298035" %>
<% f.fields_for :requirement, #event.requirement do |fields| %>
<%= fields.check_box :beamer %><br />
<% end %>
<%= f.submit %>
</div>
<% end %>
</div>
As you can see I would like to have a checkbox indicating whether a beamer is required. The problem is that the fields_for block is never evaluated. Similar to these posts:
Rails 3: fields_for showing blank filed on Edit view
Helper "fields_for" not working
As far as I can tell the objects are created properly:
# GET /events/new
def new
#event = Event.new
#event.build_requirement
end
If I use puts I see that both objects are not nil and that the associations are correct.
I am kind of new to rails and I must say that I'm stymied. Any ideas?
You should uncomment accepts_nested_attributes_for :requirement in the Event model.
Update:
You should also include = in the fields_for.
<%= f.fields_for :requirement, #event.requirement do |fields| %>

Rendering a form that creates an object that is Nested under two other models.

I'm building a rails app that has a an object that is created /nested underneath two objects.
Routes.rb
resources :pages do
resources :referralpages do
resources :rewards do
end
end
end
I've just added the rewards resource and have this for my form for creating a new reward
<%= form_for ([#referralpage, #reward]) do |f| %>
<% if #reward.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reward.errors.count, "error") %> prohibited this reward from being saved:</h2>
<ul>
<% #reward.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name %><br>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :level %><br>
<%= f.text_field :level, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :dscount %><br>
<%= f.text_field :discount, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-primary" %>
</div>
<% end %>
I need help getting the form_for ([#referralpage, #reward]) portion working.
Here's the error message I'm getting when clicking the new reward button:
undefined method `referralpage_rewards_path'
<%= form_for ([#referralpage, #reward]) do |f| %>
my guess is that it's routing to the incorrect path. What's the proper syntax to get this to work?
I think it should render this path
new_page_referralpage_reward
The point of this feature is to render rewards in the referral/show.html.erb page
I have created an index partial in my rewards view file and am rendering it in the show action of the referralpages/show.html.erb file.
I think you cannot put more than one resource path in form_for which cause invalid path.
Why you want to put 2 resource path in form?
Do you plan to save the same data for referral & rewards Model?
If, yes use just one path and make a create method in your controller to save to other model.
From this point of view:
The point of this feature is to render rewards in the
referral/show.html.erb page
If you only plan to render the data of rewards to referral/show.html.erb,
in your referral controller
def show
#rewards = Reward.all #example
end
Unless, you have model relationships like:
#Reward Model
belongs_to :refferal
#Referral Model
has_many :rewards or has_one :reward
With model realtionship:
def show
#referal = Referral.all #example
end
show.html.erb View # iterate it:
<%for referral in #referral%>
<% referral.rewards %> # need to iterate if has many
or
<%= referral.reward... %>
<%end%>

Rails select NoMethodError in Messages#new

I'm trying to put on a select box the Users who will receive the message.
What we have is one table named Messages, one named Users and one named Friendships, on message table we have user_id (sender) and friend_id (receiver) both foreign key to Users ID.
And this is the error returning: undefined method `friend_id' for #Message:0x56f6238
That been said, I'm trying to vinculate all Friendships entries with current_user id and then using friend_id to search on Users table all users that current_user is able to send message.
Any help with this error? I'm really new on Ruby On Rails development.
If I'm missing some info, let me know.
Thanks in advance
On our application, the new_message_path renders one partial which contains the following:
<%= form_for(#message) do |f| %>
<% if #message.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#message.errors.count, "error") %> prohibited this message from being saved:</h2>
<ul>
<% #message.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label "Receiver" %><br />
<%= f.select :friend_id, Message.all.collect {|friendships| [ friendships.friend_id ] }, { include_blank: true } %>
</div><br>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And on our model named Message we have this:
class Message < ActiveRecord::Base
attr_accessible :content, :friend_id
validates_presence_of :content, :friend_id, presence => true
belongs_to :user
end

Resources