I have a problem with simple model validation.
Entering materials without SKU is getting me error message:
NoMethodError in Materials#create undefined method `empty?' for
nil:NilClass
material.rb:
class Material < ActiveRecord::Base
validates :sku, :presence => true
end
materials_controler.rb (create part only):
# POST /materials
# POST /materials.json
def create
#material = Material.new(material_params)
respond_to do |format|
if #material.save
format.html { redirect_to #material, notice: 'Material was successfully created.' }
format.json { render :show, status: :created, location: #material }
else
format.html { render :new }
format.json { render json: #material.errors, status: :unprocessable_entity }
end
end
end
Your #units instance variable is nil in create action. You should set it the same way as you do in new or edit actions after your records fails validation.
Define #units also in your create method
Related
Hello I am building ROR Survey application for survey. I am having a problem of saving multiple objects into my database.My paramters after submission look all good but instead get an error of:
undefined methodpermit' for #Array:0x00007ff29d873010`
My parameters look like
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"vdUPSIU43ex1Wx3qZB4Xr6qNEaG0FbEyK2tkJ9OCcAtxK3jHe5lKVohS9JFOdpx/cISwIvzAKTRGw5zxUUS4QA==",
"survey_response"=>[
{"user_id"=>"1", "survey_question_id"=>"22", "answer"=>"Hello"},
{"user_id"=>"1", "survey_question_id"=>"23", "answer"=>"Hello"}],
"commit"=>"Create Survey response"
}
My survey_response_params methods is
def survey_response_params
params.require(:survey_response).permit(:answer, :survey_question_id, :user_id, :survey_answer_id)
end
My controller looks like :
class SurveyResponsesController < ApplicationController
def index
#survey_responses = SurveyResponse.all
end
def show
end
def new
#survey_response = SurveyResponse.new
#survey = Survey.find(1)
#survey_questions = #survey.survey_questions
end
def edit
#survey = Survey.find(1)
#survey_questions = #survey.survey_questions
end
def create
#survey_response = SurveyResponse.new(survey_response_params)
respond_to do |format|
if #survey_response.save
format.html { redirect_to #survey_response, notice: 'Survey response was successfully created.' }
format.json { render :show, status: :created, location: #survey_response }
else
format.html { render :new }
format.json { render json: #survey_response.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #survey_response.update(survey_response_params)
format.html { redirect_to #survey_response, notice: 'Survey response was successfully updated.' }
format.json { render :show, status: :ok, location: #survey_response }
else
format.html { render :edit }
format.json { render json: #survey_response.errors, status: :unprocessable_entity }
end
end
end
def destroy
#survey_response.destroy
respond_to do |format|
format.html { redirect_to survey_responses_url, notice: 'Survey response was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_survey_response
#survey_response = SurveyResponse.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def survey_response_params
params.permit(survey_response: [:answer, :survey_question_id, :user_id, :survey_answer_id])
end
end
Model
class SurveyResponse < ApplicationRecord
belongs_to :survey_question
belongs_to :user
end
You need to change your strong params, for array it looks like:
def survey_response_params
params.permit(survey_response: [:answer, :survey_question_id, :user_id, :survey_answer_id])
end
UPDATE:
I don't know anything about your models and controller, but I think it should be something like this in the controller
survey_response_params[:survey_response].each do |attrs|
SurveyResponse.new(attrs)
end
I'm having some issues with Overriding Named Route Parameters when I edit or create a post I get an error undefined method playerId for nil:NilClass. It still re-directs to the :id instead of the :playerId params only with create and edit methods.
Below, :playerId should be 101, but the 6 is the :id, not sure why it's picking it up.
SELECT `players`.* FROM `players` WHERE `players`.`playerId` = 6 LIMIT 1 [["playerId", "6"]]
Routes
resources :players, param: :playerId
Controller
def show
#player = Player.find_by(playerId: params[:playerId])
#season = PlayerStat.where("playerId = ?", #player.playerId).joins(:matches).where('matches.gameType = ?', 0).where('matches.teamId = ?', #player.teamId).group('year(matches.matchDate) DESC')
end
def edit
end
def create
#player = Player.new(player_params)
respond_to do |format|
if #player.save
format.html { redirect_to #player, notice: 'PLayer was successfully created.' }
format.json { render :show, status: :created, location: #player }
else
format.html { render :new }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
def update
#player = Player.find params[:playerId]
respond_to do |format|
if #player.update(player_params)
format.html { redirect_to #player, notice: 'Player was successfully updated.' }
format.json { render :show, status: :ok, location: #player }
else
format.html { render :edit }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
private
def set_player
#player = Player.find_by(playerId: params[:playerId])
end
def player_params
params.require(:player).permit(:playerId, :first_name, :last_name, :dob, :teamId, :jumper_no, :height, :weight, :image, team_attributes: [:teamId, :name], player_stats_attributes: [:playerId, :gameDate, :kicks, :marks])
end
undefined method playerId for nil:NilClass
The problem is params[:layerId] is nil upon a successful create or update because you aren't passing any playerId for the redirect_to. So #player is nil which resulted in that error. Changing your code to below should fix the error.
format.html { redirect_to player_path(#player.playerId), notice: 'PLayer was successfully created.' }
Same for update too.
you can define full routes like this:
get '/player/:playerId' => 'players#show'
get '/player/:playerId/edit' => 'players#edit'
v3.2.1
Not sure why 'count' is coming up nil and index won't render, as 'count' it's been fine in every model until I do the uniqueness with scope validation.
Any suggestions?
MODEL
Class FeatureIcon < ActiveRecord::Base
belongs_to :user
validates_presence_of :img_size, :feature_name, :image, :user_id
validates_uniqueness_of :img_size, :scope => :feature_name
//paperclip interpolates stuff....
end
CONTROLLER
before_filter :load_user
def index
#feature_icons = #user.feature_icons.all
#feature_icon = #user.feature_icons.new
respond_to do |format|
format.html # index.html.erb
format.json { render json: #feature_icons }
format.js
end
end
def create
#feature_icon = #user.feature_icons.new(params[:feature_icon])
respond_to do |format|
if #feature_icon.save
format.html { redirect_to user_feature_icons_url, notice: 'successfully created.' }
format.json { render json: #feature_icon, status: :created, location: #feature_icon }
format.js
else
format.html { render action: "index" }
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end
end
end
ERROR
NoMethodError in Feature_icons#create
undefined method `count' for nil:NilClass
Extracted source (around line #7):
6: <div class="count">
7: <div id="count" class="feed-count"><%= #feature_icons.count %></div>
8: </div>
In the create method, you instanciate #feature_icons (with an 's'), but in the view you're using #feature_icon (without the 's'), so #feature_icons is nil.
If the save fails, the line format.html { render action: "index" } renders the view index.htm.erb, but the method index in the controler is not not called. Try with
if #feature_icon.save
#... nothing to change
else
format.html do
#feature_icons = #user.feature_icons.all
render action: "index"
end
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end
or
if #feature_icon.save
#... nothing to change
else
format.html { redirect_to :index }
format.json { render json: #feature_icon.errors, status: :unprocessable_entity }
end
I have an object called Job that belong to another object
called client in a many relationship.
Here's my job model
class Job < ActiveRecord::Base
belongs_to :client
end
Here's my Client model
class Client < ActiveRecord::Base
has_many :jobs
end
For a new job, I simply want to assign it during creation to a client.
When I try to create a new job however. All im seeing in my view is the id of the job instead of the name and the internals of the created model are also empty.
When I try to edit the job and save it again im recieving the following error.
Client(#2157214400) expected, got String(#2151988620)
Application Trace | Framework Trace | Full Trace
app/controllers/jobs_controller.rb:61:in `block in update'
app/controllers/jobs_controller.rb:60:in `update'
I guess this could be because my controller is wrong in some way but this is my first app so im not quite sure where to look.
Here's my controller.
class JobsController < ApplicationController
def index
#job = Job.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #job }
end
end
def show
#job = Job.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #job }
end
end
def new
#job = Job.new(params[:id])
respond_to do |format|
format.html # new.html.erb
format.json { render json: #job }
end
end
def edit
#job = Job.find(params[:id])
end
def create
#job = Job.new(params[:jobs])
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'job was successfully created.' }
format.json { render json: #job, status: :created, location: #job }
else
format.html { render action: "new" }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def update
#job = Job.find(params[:id])
respond_to do |format|
if #job.update_attributes(params[:job])
format.html { redirect_to #job, notice: 'job was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def destroy
#job = Job.find(params[:id])
#job.destroy
respond_to do |format|
format.html { redirect_to :jobs }
format.json { head :no_content }
end
end
end
Any pointers or a nod in the right direction would be appreciated.
The problem is because Activerecord expected an instance of Client object , and it has method client= (because belogs_to association)
When you bind AR object from request you should use client_id parameter instead of client
you can read about http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to
if client count is short you can use select with client_id as name
Example http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html
so you can do something like that
select("job", "client_id", Client.all.collect {|c| [ c.name, c.id ] }, {:include_blank => 'None'})
instead of
f.text_field :client, :class => 'text_field'
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