I have a text_field that I want set 3 validation on this. In this text_field I get reporter's phone number. Each reporter has_one reporterprofile. I want when reporter enter his phone_number, I check validates_numericality_of and validates_length_of and if these two are true, then check uniqueness validation, If this phone_number is new, thats ok, I create a reporterprofile and redirect_to reporterprofile by this new id, But if this phone_number is exist, I want page is redirect_to this reporterprofile without created new reporter.
reporter.rb
class Reporter < ActiveRecord::Base
has_one :reporterprofile
before_create :build_reporterprofile
validates :phone_number, uniqueness: true
validates_numericality_of :phone_number
validates_length_of :phone_number, :minimum => 11, :maximum => 11
end
reporters_controller.rb
def create
#reporter = Reporter.new(reporter_params)
respond_to do |format|
if #reporter.save
format.html { redirect_to edit_reporterprofile_path(:id => #reporter.reporterprofile), notice: 'Reporter was successfully created.' }
format.json { render action: 'show', status: :created, location: #reporter }
else
if
format.html { render action: 'new' }
format.json { render json: #reporter.errors, status: :unprocessable_entity }
end
end
end
end
I can redirect_to edit_reporterprofile_path when reporter doesn't save, but if I do this, numerically and length validations are don't check. How can I redirect reporter that is exist to his profile?
First, check if a Reporter with the given phone number exists. If so, redirect to the reporterprofile path. Otherwise, create the new reporter. There are various ways to organize the logic to handle this. Here it is all shoved into the "create" action of the reporters controller.
def create
existing_reporter = Reporter.includes(:reporterprofile).find_by(phone_number: reporter_params[:phone_number])
if existing_reporter
redirect_to reporterprofile_path(existing_reporter.reporterprofile)
else
#reporter = Reporter.new(reporter_params)
respond_to do |format|
if #reporter.save
format.html { redirect_to edit_reporterprofile_path(:id => #reporter.reporterprofile), notice: 'Reporter was successfully created.' }
format.json { render action: 'show', status: :created, location: #reporter }
else
if
format.html { render action: 'new' }
format.json { render json: #reporter.errors, status: :unprocessable_entity }
end
end
end
end
end
I'd start by populating the validates method with more than what you've got now. This will remove the dependency on the other two methods you have, which should go to fixing some of the issue:
validates :phone_number,
length: { is: 6 },
numericality: true,
uniqueness: true
Related
I have this code that validates by user_id. If the category_name exists, this prevents the creation of a new Object. The code works but I don't believe this is best practice.
def create
#item_category = ItemCategory.new(item_category_params)
#item_category.user_id = current_user.id
search = ItemCategory.where(:name => #item_category.name,:user_id => current_user.user_id)
if search.blank?
respond_to do |format|
if #item_category.save
format.html { redirect_to :back, notice: 'Se ha creado la categoria' }
format.json { render action: 'show', status: :created, location: #item_category }
else
format.html { render action: 'new' }
format.json { render json: #item_category.errors, status: :unprocessable_entity }
end
end
else
respond_to do |duplicate|
duplicate.html { redirect_to #item_category, alert: 'Categoria Repetida' }
duplicate.json { render json: #item_category.errors, status: :unprocessable_entity}
end
end
end
Thanks.
It would be better to put the validation in your ItemCategory model...
class ItemCategory < ActiveRecord::Base
validates_uniqueness_of :name, :scope => :user_id
...
end
I tried to validate associated attribute access_module_id in role
model but it doesn't work. How to give validation of presence: true to other model's attribute in role form? Here is associations
role.rb
class Role < ActiveRecord::Base
....
has_many :access_module_roles, :dependent => :destroy
has_many :access_modules, through: :access_module_roles
validates :name,:access_module_id, presence: true # I want to validate presence of access_module_ids in role form
end
access_module.rb
class AccessModule < ActiveRecord::Base
has_many :access_module_roles
has_many :roles, through: :access_module_roles
end
access_module_roles.rb
class AccessModuleRole < ActiveRecord::Base
belongs_to :access_module
belongs_to :role
end
Update
I have tried below validation and if I select one, two or all still getting an error like
"Access module ids can't be blank"
validates_presence_of :access_module_ids
Controller
def create
#role = Role.new(role_params)
respond_to do |format|
if #role.save
params[:role][:access_module_ids].each do |acmi|
AccessModuleRole.create!(:role_id => #role.id, :access_module_id => acmi) if acmi!=""
end
format.html { redirect_to roles_path, notice: 'Role was successfully created.' }
format.json { render :index, status: :created, location: #role }
else
format.html { render :new }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
I found that I am doing mistake in Create method. I was inserting data to AccessModuleRole after doing save so it gets validation error while creating..And was getting parameter as nil
Corrected code:
def create
#role = Role.new(role_params)
#role.access_module_ids = params[:role][:access_module_ids]
respond_to do |format|
if #role.save
format.html { redirect_to roles_path, notice: 'Role was successfully created.' }
format.json { render :index, status: :created, location: #role }
else
format.html { render :new }
format.json { render json: #role.errors, status: :unprocessable_entity }
end
end
end
Permitted Role's attributes:
private
def role_params
params.require(:role).permit(:name,:chk_ids ,:description, :code, :is_active, :access_module_ids)
end
Now it works perfectly.. Thanks to RAJ to pointing me :)
I have basic form that is accessed, for example via: http://url.com/rentals/new/dvd/10.
The problem is when form error happens I can't redirect it to the same page with the same
url segments and show the form error messages.
rentals_controller.rb:
def create
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
routes.rb
get 'rentals/new/dvd/:dvd_id' => 'rentals#new', as: :new_dvd_rental
I have the following models created:
dvd.rb
class Dvd < ActiveRecord::Base
has_many :rentals
has_many :users, through: :rentals
validates :title, presence: true
validates :year, inclusion: {in: 1900..Time.now.year.to_i}, :presence => {:message => 'Year must be from 1900 till current year.'}
validates :length, inclusion: {in: 1..999}, :presence => {:message => 'DVD length must be in minutes in range 1..999.'}
end
rental.rb
class Rental < ActiveRecord::Base
belongs_to :user
belongs_to :dvd
validates :user_id, presence: true
validates :total_price, presence: true
end
user.rb
class User < ActiveRecord::Base
has_many :rentals
has_many :dvds, through: :rentals
end
As well as rentals_controller.rb:
class RentalsController < ApplicationController
before_action :set_rental, only: [:show, :edit, :update, :destroy]
# GET /rentals
# GET /rentals.json
def index
#rentals = Rental.all
end
# GET /rentals/1
# GET /rentals/1.json
def show
end
# GET /rentals/new
def new
#rental = Rental.new
#users = User.all
#dvd = Dvd.find(params[:dvd_id])
end
# GET /rentals/1/edit
def edit
end
# POST /rentals
# POST /rentals.json
def create
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /rentals/1
# PATCH/PUT /rentals/1.json
def update
respond_to do |format|
if #rental.update(rental_params)
format.html { redirect_to #rental, notice: 'Rental was successfully updated.' }
format.json { render :show, status: :ok, location: #rental }
else
format.html { render :edit }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
# DELETE /rentals/1
# DELETE /rentals/1.json
def destroy
#rental.destroy
respond_to do |format|
format.html { redirect_to rental_url, notice: 'Rental was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_rental
#rental = Rental.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def rental_params
params.require(:rental).permit(:dvd_id, :user_id, :rent_date, :return_date, :total_price, :returned)
end
end
I've tried to modify rental controller like this, but still do not know how to pass other segments like new and dvd:
render :action => "new", :dvd_id => params[:dvd_id]
Any ideas?
I think if you draw a more restful route like this
resources :dvds do
resources :rentals
end
you will get the routes like http://url.com/dvd/10/rentals/new
here you will always get dvd_id
and in rentals_controller create method look like
def create
#dvd = Dvd.find(params[:dvd_id])
#rental = Rental.new(rental_params)
respond_to do |format|
if #rental.save
format.html { redirect_to #rental, notice: 'Rental was successfully created.' }
format.json { render :show, status: :created, location: #rental }
else
format.html { render :new }
format.json { render json: #rental.errors, status: :unprocessable_entity }
end
end
end
-- Waiting for #Sanket's ideas
Routes
The issue will almost certainly be with your redirect_to method
The problem is that your controller doesn't know you're using a nested resource, and consequently when you redirect to an object, it will likely just take you to the simplest route it can find
I would try this:
def create
...
else
format.html { render your_nested_resource_path(dvd_id: params[:dvd_id], other: params[:params]) }
...
end
This allows you to send the request to the nested route, which Rails won't route to without support
I am Trying to check if User_avatar is present or not from form(submitted by user).If he is select different image to update i need to go for cropping otherwise it will redirect to edit page.
But If i run bellow code on controller it is directly redirecting to edit page if i select and send image also.
Controller
if #user.update(user_params)
if((#user.user_avatar.present?) && (!params[:user_avatar].blank?) )
format.html { render :action => 'crop'}
else
format.html { redirect_to edit_user_path, notice: 'user was successfully updated.' }
format.json { head :no_content }
end
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
def user_params
params.require(:user).permit(:user, :crop_x, :crop_y, :crop_w, :crop_h, :user_avatar, :fname, :lname, :city_id, :location_id, :email, :password, :course, :phone_no)
end
In rails you can use has_key? method which returns true or false, rewriting the above if condition
if #user.user_avatar.present? and params[:user].has_key?(:user_avatar)
# your code
end
I'm a bit new in ruby/rails/POO and I'm a bit lost in a form that I'm realizing.
I'm using the gem formtastic and I'm doing it in haml.
I have this model
class Help < ActiveRecord::Base
attr_accessible :answer, :category, :question
validates :category, presence: true, uniqueness: true
validates :question, presence: true
validates :answer, presence: true
end
In my form, I want the possibility to create a new Question/Answer with its category.
The category should be selected in a selectbox but if the category I want is not listed yet, I want to have the ability to add it.
Here's the form
= semantic_form_for #help do |f|
= f.inputs do
= f.input :category, :as => :select, :collection => Help.category
= f.input :category
= f.input :question
= f.input :answer
= f.action :submit, :as => :button
EDIT :
class HelpsController < ApplicationController
# GET /helps
# GET /helps.json
def index
#helps = Help.all.sort_by {|f| f.category}
respond_to do |format|
format.html # index.html.erb
format.json { render json: #helps }
end
end
# GET /helps/1
# GET /helps/1.json
def show
#help = Help.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #help }
end
end
# GET /helps/new
# GET /helps/new.json
def new
#help = Help.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #help }
end
end
# GET /helps/1/edit
def edit
#help = Help.find(params[:id])
end
# POST /helps
# POST /helps.json
def create
#help = Help.new(params[:help])
respond_to do |format|
if #help.save
format.html { redirect_to #help, notice: 'Help was successfully created.' }
format.json { render json: #help, status: :created, location: #help }
else
format.html { render action: "new" }
format.json { render json: #help.errors, status: :unprocessable_entity }
end
end
end
# PUT /helps/1
# PUT /helps/1.json
def update
#help = Help.find(params[:id])
respond_to do |format|
if #help.update_attributes(params[:help])
format.html { redirect_to #help, notice: 'Help was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #help.errors, status: :unprocessable_entity }
end
end
end
# DELETE /helps/1
# DELETE /helps/1.json
def destroy
#help = Help.find(params[:id])
#help.destroy
respond_to do |format|
format.html { redirect_to helps_url }
format.json { head :no_content }
end
end
end
When I try to reach /help/new it actually says to me :
undefined method `model_name' for NilClass:Class
The aim is to have in the selectbox, categories already registered, and if the user is not founding the category he wants to use in the selectbox, he can create one by typing it in the input.
Any clues to help me doing this ?
Cordially ,
Rob
Try this:
= f.collection_select :category
I found a method that does half what i wanted.
It's the method pluck.
I defined a static method in my model :
def self.getcat
Help.pluck(:category)
end
Then in my form in simply call this method on my collection :
= f.input :category, :as => :select, :collection => Help.getcat