I am doing a basic validation for a bank entry and am trying to display the errors on submit. Here is my validation and html.
controller:
class PagesController < ApplicationController
def index
#guestbook_entries = GuestbookEntry.all
#guestbook_entry = GuestbookEntry.new
render "welcome"
end
end
class GuestbookEntry < ActiveRecord::Base
validates :body, presence: :true
end
This is my html:
<% form_for #guestbook_entry do |f| %>
<% if f.errors.any? %>
<% f.errors.full_messages.each do |m| %>
<li><%= m %></li>
<% end %>
<% end %>
<%= f.label :body, "Guestbook Entry:" %>
<%= f.text_area :body %>
<%= f.submit "Submit" %>
<% end %>
Any ideas?
Related
I'm implementing a voting system where when the course is already upvoted/downvoted, clicking downvote/upvote will switch to that vote respectively and clicking again will delete that vote (similar to Reddit).
While voting and destroying vote perform correctly, I'm having trouble trying to update the vote with form_for and patch method, where the value of the vote_type returns nil
My Votes_Controller
class VotesController < ApplicationController
def create
#vote = Vote.new(secure_params)
#vote.course = Course.find(params[:course_id])
if #vote.save
respond_to do |format|
format.html { redirect_to :courses }
format.js
end
end
def update
vote = Vote.find_by(user: current_user)
vote.update_attribute(:vote_type, update_vote_params)
redirect_to :courses
end
def destroy
vote = Vote.find_by(user: current_user)
vote.destroy
redirect_to :courses, :notice => 'Unvoted!'
end
private
def secure_params
params.require(:vote).permit( :user_id, :vote_type )
end
def update_vote_params
params.require(:vote).permit(:vote_type)
end
end
My index.html.erb
<% if Vote.exists?(user: current_user) && Vote.find_by(user: current_user).vote_type.equal?(-1) %>
<%= form_for course.votes.build, url: course_vote_path(course, Vote.find_by(user: current_user).id), method: :patch do |f| %>
<%= f.hidden_field :vote_type, value: 1 %>
<%= f.submit 'Upvote', class: 'btn btn-default' %>
<% end %>
<% elsif Vote.exists?(user: current_user) && Vote.find_by(user: current_user).vote_type.equal?(1) %>
<%= form_for course.votes.build, url: course_vote_path(course, Vote.find_by(user: current_user).id), method: :delete do |f| %>
<%= f.submit "Upvote", class: 'btn btn-default' %>
<% end %>
<% else %>
<%= form_for course.votes.build, url: course_votes_path(course) do |f| %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.hidden_field :vote_type, value: 1 %>
<%= f.submit 'Upvote', class: 'btn btn-default' %>
<% end %>
<% end %>
My routes.rb
Rails.application.routes.draw do
get 'vote/create'
get 'vote/destroy'
get 'courses/new'
get 'users/new'
resources :courses do
resources :votes, only: [:create, :destroy, :update]
end
resources :users
end
I expect the param to pass 1 for vote_type, however, the actual output is nil
new.html is a registration form ,which creates tutor account .
It involves error handling . _error_messages.html.erb is the file which handles the error ,like should be filling in all text fields .
e.g , showing :
`
The form contains 3 errors.
Name can't be blank
Password confirmation can't be blank
Password confirmation doesn't match Password
However ,when submits the form without any input in new.html ,it shows the error
Missing template tutors/register, application/register with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in: * "C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.0.0/lib/action_dispatch/templates" * "D:/Sites/abc/app/views"
new.html.erb
<% provide(:title, 'Registeration') %>
<h1>Tutor Registration</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#tutor) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.label :gender %>
<%= f.select(:gender, ['Male', 'Female'] , class: 'form-control' )%>
<%= f.label :tutor_education_level %>
<%= f.select(:education_level, ['Bachelor', 'Master', 'Doctor'] , class: 'form-control' )%>
<%= f.label :tutor_institution %>
<%= f.text_field :institution, class: 'form-control' %>
<%= f.label :tutorial_experience %>
<%= f.text_field :experience, class: 'form-control' %>
<%= f.label :tutor_preferred_district %>
<%= f.text_field :district, class: 'form-control' %>
<%= f.label :tutor_preferred_subject %>
<%= f.text_field :subject, class: 'form-control' %>
<%= f.label :tutor_required_student_level %>
<%= f.select(:student_level, ['P1-P3', 'P4-P6', 'S1-S3', 'S4-S6'] , class: 'form-control' )%>
<%= f.submit "Create tutor's account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
views/shared/_error_messages.html.erb
<% if #tutor.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(#tutor.errors.count, "error") %>.
</div>
<ul>
<% #tutor.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Tutor -controller
class TutorsController < ApplicationController
before_action :logged_in_tutor, only: [:edit, :update]
before_action :correct_tutor, only: [:edit, :update]
def index
#tutors = Tutor.all
end
def show
#tutor = Tutor.find(params[:id])
end
def new
#tutor = Tutor.new
end
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
log_in #tutor
flash[:success] = "Congratulations! Your registration is successful!"
redirect_to #tutor
else
render 'register'
end
end
def edit
#tutor = Tutor.find(params[:id])
end
def update
if #tutor.update_attributes(tutor_params)
flash[:success] = "Profile updated successfuly!"
redirect_to #tutor
else
render 'edit'
end
end
# Handle sign-up failure, to redirect the tutor to the registeration form again
def tutor_params
params.require(:tutor).permit(:name, :email, :password, :password_confirmation, :address,:gender ,:education_level,:institution,:exprience,:district,:subject,:student_level)
end
def logged_in_tutor
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def correct_tutor
#tutor = Tutor.find(params[:id])
redirect_to(root_url) unless current_tutor?(#tutor)
end
end
When you submit the form, request sends to the create action:
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
# if #tutor valid save it and redirect to show action
redirect_to #tutor
else
# else render the register template(or action)
render 'register'
end
end
In the create action there is a conditional if, in the first case all is good, #tutor has been saved and Rails call redirect to show action, otherwise Rails trying to render register template which is not exists(the errors claims about it). To resolve that issue create register template with desired html code which should run if #tutor isn't saved.
I have a Post model and Tag model with many to many relationships.
Post Model:
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
end
Tag model:
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
I also have a join table for posts_tags :
class JoinPostsAndTags < ActiveRecord::Migration
def change
create_table :posts_tags do |t|
t.integer :tag_id
t.integer :post_id
t.timestamps null: false
end
end
end
Now, I need to provide multiple selection for selecting tags for a post.
Below is the post form.html.erb
<%= form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Name %><br>
<%= f.text_field :Name %>
</div>
<div class="field">
<%= f.label :Email %><br>
<%= f.text_field :Email %>
</div>
<div class="field">
<%= f.label :Message %><br>
<%= f.text_area :Message %>
</div>
<% #tags= Tag.all %>
<% if #tags %>
<% #tags.each do |tag| %>
<div>
<%= check_box_tag "post[tag_ids][]", tag.id, #post.tags.include?(tag) %>
<%= tag.name %>
</div>
<% end %>
<% end %>
<br><br>
<%= link_to 'Create Tag', tags_path %>
<br><br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It is not adding the selected tags to the post. I need to add the selected tags to the post. How can I do it.
But, in rails console if I use post= Post.first tag= Tag.first post.tags<<tag it adds the tag to the post.
I don't have any special code in post controller to handle this. Please help me.
Add {tag_ids:[]} to your params permit arguments in your PostsController, like so:
def post_params
params.require(:post).permit(:name, :email, :message, {tag_ids:[]})
end
I am new to ruby. I have the same form but i need it to perform creation/updation as and when required. The problem i have now is that whenever i call edit instead of editing the details of an existing user, i am getting a new user with the edited details. To put it simply, i think whenever i perform edit, the create method is being called.
So is there any way to use single form for both new and edit instead of using separate forms.
The following code is for editing user details:
<%= link_to 'Home', root_path %>
<h2>Edit user</h2>
<%= form_for :user, url: user_index_path do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
The following code is for creating user:
<%= link_to 'Home', root_path %>
<h2>Create new user</h2>
<%= form_for :user, url: user_index_path do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
And this is my controller:
class UserController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
##user = User.find(params[:id])
if #user.update(user_params)
redirect_to #user
else
render 'edit'
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
redirect_to user_index_path
end
private
def user_params
params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
end
end
Since i am new to ruby, i did not get the exact details of how http requests function in ruby.
users/_form.html.erb
<%= link_to 'Home', root_path %>
<%= form_for #user do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :address %><br>
<%= f.text_area :address %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :state %><br>
<%= f.text_field :state %>
</p>
<p>
<%= f.label :country %>
<%= f.collection_select(:country, Country.all, :name, :name) %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
users/new.html.erb
<h2>Create new user</h2>
<%= render 'form' %>
users/edit.html.erb
<h2>Edit user</h2>
<%= render 'form' %>
users_controller.rb
class UsersController < ApplicationController
before_filter :find_user, only: [:show, :edit, :update, :destroy]
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
def edit
end
def update
if #user.update(user_params)
redirect_to #user
else
render 'edit'
end
end
def destroy
#user.destroy
redirect_to user_index_path
end
private
def user_params
params.require(:user).permit(:name, :address, :email, :phone, :state, :country)
end
def find_user
#user = User.find(params[:id])
end
end
When you have same view code for two or more methods, you should create a partial of same view code and render it in those methods. This is called DRY principle in ruby on rails
I have a nested form.
Right now I want to arrange the layout with some CSS but I am facing trouble allocating dom ids to the form.
This is the subject controller.
I want to allocate lesson_type as seen in line 5 as the dom id.
1 def index
2 #subjects = Subject.all
3 #subject = Subject.new
4 lecture = #subject.lessons.build
5 lecture.lesson_type = "lecture"
lecture.lesson_groups.build
lecture.destroy
tutorial = #subject.lessons.build
tutorial.lesson_type = "tutorial"
tutorial.lesson_groups.build
tutorial.destroy
laboratory = #subject.lessons.build
laboratory.lesson_type = "laboratory"
laboratory.lesson_groups.build
laboratory.destroy
respond_to do |format|
format.html # index.html.erb
format.json { render json: #subjects }
format.js
end
end
The following is the form.
<%= nested_form_for(#subject, :remote=>true) do |f| %>
<% if #subject.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#subject.errors.count, "error") %> prohibited this subject from being saved:</h2>
<ul>
<% #subject.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :subject_code %><br />
<%= f.text_field :subject_code %>
</div>
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
<%= lesson.fields_for :lesson_groups do |lesson_group| %>
<%= lesson_group.label :group_index %><br/>
<%= lesson_group.text_field :group_index %>
<%= lesson_group.link_to_remove "Remove this task" %>
<% end %>
This is the div where I want to add an id to.
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
I have tried out the following but it did not worked.
<div id = "<%= :lesson_type%>">
Would appreciate it if someone could help me out thanks.
sorry..
#controller
def index
...
lecture.lesson_type = #lesson_dom_id = "lecture" # line 5
...
end
#view
<div id="<%= #lesson_dom_id %>">