Trying to build a route that can display pages with varying information about various types of candy.
the route recognizes URL paths but want it to only show valid candy types e.g kit_kat, gummy_bear, twizzler Any other type of candy specified should generate a 404 status code
Generated a scaffold to allow anyone to add candy types but when i try to pass the valid candy types ( kit_kat etc) I get error
Rails 4.2 NameError in CandiesController#create
undefined local variable or method ` params' for #
**candy_controller.rb**
class CandiesController < ApplicationController
before_action :set_candy, only: [:show, :edit, :update, :destroy]
# GET /candies
# GET /candies.json
def index
#candies = Candy.all
end
# GET /candies/1
# GET /candies/1.json
def show
end
# GET /candies/new
def new
#candy = Candy.new
end
# GET /candies/1/edit
def edit
end
# POST /candies
# POST /candies.json
def create
if (([:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
:twizzler]).any? { |word| params[:title].includes?(word) })
#candy = Candy.new(candy_params)
respond_to do |format|
if #candy.save
format.html { redirect_to #candy, notice: 'Candy was successfully created.' }
format.json { render :show, status: :created, location: #candy }
else
format.html { render :new }
format.json { render json: #candy.errors, status: :unprocessable_entity }
end
end
end
end
# PATCH/PUT /candies/1
# PATCH/PUT /candies/1.json
def update
respond_to do |format|
if #candy.update(candy_params)
format.html { redirect_to #candy, notice: 'Candy was successfully updated.' }
format.json { render :show, status: :ok, location: #candy }
else
format.html { render :edit }
format.json { render json: #candy.errors, status: :unprocessable_entity }
end
end
end
# DELETE /candies/1
# DELETE /candies/1.json
def destroy
#candy.destroy
respond_to do |format|
format.html { redirect_to candies_url, notice: 'Candy was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_candy
#candy = Candy.friendly.find(params[:id])
end
# Use callbacks to share common setup or constraints between actions.
# Never trust parameters from the scary internet, only allow the white list through.
def candy_params
params.require(:candy).permit(:title, :discription)
end
end
candy.rb
class Candy < ActiveRecord::Base
extend FriendlyId
friendly_id :title, use: :slugged
end
updated candy_controller.rb
def create
if candy[:title] && !candy[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
:twizzler].include?(candy[:title].to_sym)
#candy = Candy.new(candy_params)
respond_to do |format|
if #candy.save
format.html { redirect_to #candy, notice: 'Candy was successfully created.' }
format.json { render :show, status: :created, location: #candy }
else
format.html { render :new }
format.json { render json: #candy.errors, status: :unprocessable_entity }
end
end
end
end
updated code
def create
if candy_params[:title] && !candy_params[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
:twizzler].include?(candy_params[:title].to_sym)
#candy = Candy.new(candy_params)
respond_to do |format|
if #candy.save
format.html { redirect_to #candy, notice: 'Candy was successfully created.' }
format.json { render :show, status: :created, location: #candy }
else
format.html { render :new }
format.json { render json: #candy.errors, status: :unprocessable_entity }
end
end
end
end
A couple of things,
First, params doesn't have :title, :title is in params[:candy][:title], or you just use candy_params[:title]
Second, the if statement could be shorter
if candy_params[:title] && !candy_params[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
:twizzler].include?(candy_params[:title].to_sym)
(Go on and create the candy)
else
(Redirect with error messages | Wrong Candy Type)
end
It's always good to check the existence of the params and make sure it's not empty first, then check if it's included in the acceptable list. Notice that your original code was to compare symbol with string, so cast them to the same type and check.
UPDATE
Added else statement for redirect when :title isn't present, empty string, or wrong type
Related
ActionController::UrlGenerationError in PersonelsController#create
No route matches {:action=>"show", :controller=>"personels", :id=>nil},
missing required keys: [:id]
Extracted source (around line #31):
respond_to do |format|
if #personel.save
format.html { redirect_to #personel, notice: 'Personel was successfully created.' }
format.json { render :show, status: :created, location: #personel }
else
format.html { render :new }
After creating the "Personel" I get such an error. There is no problem in the process. "Personel" added.I dont have idea about it.
class PersonelsController < ApplicationController
before_action :set_personel, only: [:show, :edit, :update, :destroy]
console
# GET /personels
# GET /personels.json
def index
#personels = Personel.all
end
# GET /personels/1
# GET /personels/1.json
def show
end
# GET /personels/new
def new
#personel = Personel.new
end
# GET /personels/1/edit
def edit
end
# POST /personels
# POST /personels.json
def create
#personel = Personel.new(personel_params)
respond_to do |format|
if #personel.save
format.html { redirect_to #personel, notice: 'Personel was successfully created.' }
format.json { render :show, status: :created, location: #personel }
else
format.html { render :new }
format.json { render json: #personel.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /personels/1
# PATCH/PUT /personels/1.json
def update
respond_to do |format|
if #personel.update(personel_params)
format.html { redirect_to #personel, notice: 'Personel was successfully updated.' }
format.json { render :show, status: :ok, location: #personel }
else
format.html { render :edit }
format.json { render json: #personel.errors, status: :unprocessable_entity }
end
end
end
# DELETE /personels/1
# DELETE /personels/1.json
def destroy
#personel.destroy
respond_to do |format|
format.html { redirect_to personels_url, notice: 'Personel was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_personel
#personel = Personel.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def personel_params
params.require(:personel).permit(:name, :surname, :tc_no, :date_of_start, :date_of_finish, :department_id, :job_rotation_id)
end
end
This is my route
Rails.application.routes.draw do
resources :personels
resources :job_rotations
resources :departments
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Try using redirect_to path, like:
redirect_to personel_path(#personel)
I have the web app on RoR, but the issue is once the user upload the image, the product_id is not associated with the product_attachments. Not until I proceed to next form.
Following were my controller
ProductAttachmentsController:
class ProductAttachmentsController < ApplicationController
before_action :set_product_attachment, only: [:show, :edit, :update, :destroy]
def index
#product_attachments = ProductAttachment.all
end
def show
end
def new
#product_attachment = ProductAttachment.new
end
def create
#product_attachment = ProductAttachment.new(product_attachment_params)
respond_to do |format|
if #product_attachment.save
format.html { redirect_to #product_attachment, notice: 'Product attachment was successfully created.' }
format.json {render :json => #product_attachment}
else
format.html { render :new }
format.json { render json: #product_attachment.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #product_attachment.update(product_attachment_params)
format.html { redirect_to #product_attachment.product, notice: 'Product attachment was successfully updated.' }
format.json { render :show, status: :ok, location: #product_attachment }
else
format.html { render :edit }
format.json { render json: #product_attachment.errors, status: :unprocessable_entity }
end
end
end
def destroy
#product_attachment.destroy
respond_to do |format|
format.html { redirect_to product_attachments_url, notice: 'Product attachment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product_attachment
#product_attachment = ProductAttachment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_attachment_params
params.require(:product_attachment).permit(:product_id, :attachment)
end
end
How can I trick the create method, so it will create a product_id when I create product_attachment? Currently I need to proceed next step and it trigger update method to insert product_id in product_attachments table. Thanks!!
You can store the product attachment id in a session variable
if #product_attachment.save
session[:product_attachment] = #product_attachment.id ### HERE!
format.html { redirect_to #product_attachment, notice: 'Product attachment was successfully created.' }
format.json {render :json => #product_attachment}
else
format.html { render :new }
format.json { render json: #product_attachment.errors, status: :unprocessable_entity }
end
When you create the product (in the ProductsController ) recall the attachment and update the product_id
if #product.save
if session[:product_attachment]
ProductAttachment.find(session[:product_attachment]).update_attribute(:product_id, #product.id)
session[:product_attachment] = nil
end
...
end
Hello I am trying to store a PDF document in a PostgreSQL database using Ruby Rails.
Currently my code looks like this:
DB File:
'$20151126021922_create_pdf_creates.rb'
class CreatePdfCreates < ActiveRecord::Migration
def change
create_table :pdf_creates do |t|
t.binary :pdfload
t.timestamps null: false
end
end
end
Model:
'$pdf_create.rb'
class PdfCreate < ActiveRecord::Base
end
Controller:
'$pdf_creates_controller.rb'
class PdfCreatesController < ApplicationController
before_action :set_pdf_create, only: [:show, :edit, :update, :destroy]
# GET /pdf_creates
# GET /pdf_creates.json
def index
#pdf_creates = PdfCreate.all
end
# GET /pdf_creates/1
# GET /pdf_creates/1.json
def show
end
# GET /pdf_creates/new
def new
#pdf_create = PdfCreate.new
end
# GET /pdf_creates/1/edit
def edit
end
# POST /pdf_creates
# POST /pdf_creates.json
def newpdf
#pdf_create = PdfCreate.new(pdf_create_params)
respond_to do |format|
if #pdf_create.save
format.html { redirect_to #pdf_create, notice: 'Pdf create was successfully created.' }
format.json { render :show, status: :created, location: #pdf_create }
else
format.html { render :new }
format.json { render json: #pdf_create.errors, status: :unprocessable_entity }
end
end
end
def create
#pdf_create = PdfCreate.new(pdf_create_params)
#data = File.read(Rails.root + "tmp/consent(1).pdf")
#Document.create pdfload: data
respond_to do |format|
if #pdf_create.save
format.html { redirect_to #pdf_create, notice: 'Pdf create was successfully created.' }
format.json { render :show, status: :created, location: #pdf_create }
format.pdf { send_data #pdf_create.render}
else
format.html { render :new }
# format.json { render json: #pdf_create.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /pdf_creates/1
# PATCH/PUT /pdf_creates/1.json
def update
respond_to do |format|
if #pdf_create.update(pdf_create_params)
format.html { redirect_to #pdf_create, notice: 'Pdf create was successfully updated.' }
format.json { render :show, status: :ok, location: #pdf_create }
else
format.html { render :edit }
format.json { render json: #pdf_create.errors, status: :unprocessable_entity }
end
end
end
# DELETE /pdf_creates/1
# DELETE /pdf_creates/1.json
def destroy
#pdf_create.destroy
respond_to do |format|
format.html { redirect_to pdf_creates_url, notice: 'Pdf create was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_pdf_create
#pdf_create = PdfCreate.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def pdf_create_params
params.require(:pdf_create).permit(:pdfload)
end
end
I send a pdf form and the result that is returned is me:
{"id":5,"pdfload":null,"created_at":"2015-11-26T03:24:37.457Z","updated_at":"2015-11-26T03:24:37.457Z"}
What is wrong? Tks
You're sending the whole newly created record, not the PDF data stored in it.
Try changing this:
format.pdf { send_data #pdf_create.render}
to this:
format.pdf { send_data #pdf_create.pdfload}
how to customize scaffold generator #was following this link
class IdeasController < ApplicationController
before_action :set_idea, only: [:show, :edit, :update, :destroy]
# GET /ideas
# GET /ideas.json
def index
#ideas = Idea.all
end
# GET /ideas/1
# GET /ideas/1.json
def show
end
# GET /ideas/new
def new
#idea = Idea.new
end
# GET /ideas/1/edit
def edit
end
# POST /ideas
# POST /ideas.json
def create
#idea = Idea.new(idea_params)
respond_to do |format|
if #idea.save
format.html { redirect_to #idea, notice: 'Idea was successfully created.' }
format.json { render action: 'show', status: :created, location: #idea }
else
format.html { render action: 'new' }
format.json { render json: #idea.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /ideas/1
# PATCH/PUT /ideas/1.json
def update
respond_to do |format|
if #idea.update(idea_params)
format.html { redirect_to #idea, notice: 'Idea was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #idea.errors, status: :unprocessable_entity }
end
end
end
# DELETE /ideas/1
# DELETE /ideas/1.json
def destroy
#idea.destroy
respond_to do |format|
format.html { redirect_to ideas_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_idea
#idea = Idea.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def idea_params
params.require(:idea).permit(:name, :description, :picture)
end
end
How to remove all the respond_to code ?
Use respond_with to make your controllers cleaner. This apidoc and
this screencast will answer all your related questions.
Your controller methods will be as clean as this:
def update
#idea.update(idea_params)
respond_with #idea, notice: 'Idea was successfully updated.'
end
To apply that to default scaffold controller template, just copy the template content from github and put it into RAILS_ROOT/lib/templates/rails/scaffold_controller/controller.rb. Then apply the respond_with approach there.
Just do so like this.
For e.g.
respond_to do |format|
if #idea.save
format.html { redirect_to #idea, notice: 'Idea was successfully created.' }
format.json { render action: 'show', status: :created, location: #idea }
else
format.html { render action: 'new' }
format.json { render json: #idea.errors, status: :unprocessable_entity }
end
end
can be replaced with
if #idea.save
redirect_to #idea, notice: 'Idea was successfully created.'
else
render 'new
end
Hello guys I've 2 models: User(aka parent) and Profil(aka child).And I want to limit the number of profil for a user to one.
models/user.rb
class User < ActiveRecord::Base
has_one :profil
end
models/profil.rb
class Profil < ActiveRecord::Base
attr_accessible :logo
belongs_to :user
mount_uploader :logo, ImageUploader
validate :limit_profil_to_one, :on => :create
def limit_profil_to_one
if self.user.profils(:reload).count > 1
errors.add(:base, "Exceeded thing limit")
end
end
end
But when I try to create a profil I get the following error message:
NoMethodError (undefined method `profils' for nil:NilClass):
app/models/profil.rb:11:in `limit_profil_to_one'
app/controllers/profils_controller.rb:52:in `block in create'
app/controllers/profils_controller.rb:51:in `create
controllers/profils_controller.rb
# -*- encoding : utf-8 -*-
class ProfilsController < ApplicationController
# GET /factures
# GET /factures.json
def index
#profils = Profil.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #profil }
end
end
# GET /profils/1
# GET /profils/1.json
def show
#profil = Profil.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #profil }
end
end
# GET /profils/new
# GET /profils/new.json
def new
#profil = Profil.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #profil }
end
end
# GET /profils/1/edit
def edit
#profil = Profil.find(params[:id])
end
# POST /profils
# POST /profils.json
def create
#profil = Profil.new(params[:profil])
respond_to do |format|
if #profil.save
format.html { redirect_to #profil, notice: 'Profil was successfully created.' }
format.json { render json: #profil, status: :created, location: #profil }
else
format.html { render action: "new" }
format.json { render json: #profil.errors, status: :unprocessable_entity }
end
end
end
# PUT /profils/1
# PUT /profils/1.json
def update
#profil = Profil.find(params[:id])
respond_to do |format|
if #profil.update_attributes(params[:profil])
format.html { redirect_to #profil, notice: 'Profil was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #profil.errors, status: :unprocessable_entity }
end
end
end
# DELETE /factures/1
# DELETE /factures/1.json
def destroy
#profil = Profil.find(params[:id])
#profil.destroy
respond_to do |format|
format.html { redirect_to profils_url }
format.json { head :ok }
end
end
end
What I am doing wrong?
Look at line 2 in the limit_profil_to_one - self.user is nil so it is failing.
def limit_profil_to_one
if self.user.profils(:reload).count > 1 # self.user is nil
errors.add(:base, "Exceeded thing limit")
end
end
I am making some assumptions about what your app is doing, but for this post I am going to assume that your controller has a current user defined in the controller and that you are creating a Profil for that User (side: note, what is a profil? I am assuming you actually mean profile) You should set the user in the controller to the user it is supposed to be, like so.
def create
#profil = Profil.new(params[:profil])
#profil.user = current_user # however you access the currently logged in user
respond_to do |format|
if #profil.save
format.html { redirect_to #profil, notice: 'Profil was successfully created.' }
format.json { render json: #profil, status: :created, location: #profil }
else
format.html { render action: "new" }
format.json { render json: #profil.errors, status: :unprocessable_entity }
end
end
end