Overriding Named Route Parameters edit and create - ruby-on-rails

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'

Related

Not able to update data in database form

I am getting error - undefined method collect for nil:NilClass, but I am able to render option list from another database table, and also able to save data in stage table but not able to update it.
I am rendering option list form responsibility table in stage form field responsibility option and saves that option into stage table.
stages_controller.rb
def index
redirect_to project_path(#project)
end
def show
end
def new
#stage = Stage.new
#responsibilities = #project.responsibilities
end
def edit
end
def create
#responsibilities = #project.responsibilities
#stage = #project.stages.build(stage_params)
respond_to do |format|
if #stage.save
format.html { redirect_to project_path(#project), notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def update
#responsibilities = #project.responsibilities
respond_to do |format|
if #stage.update(stage_params)
format.html { redirect_to project_stages_url, notice: 'Stage was successfully updated.' }
format.json { render :show, status: :ok, location: #stage }
else
format.html { render :edit }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def destroy
#stage.destroy
respond_to do |format|
format.html { redirect_to project_stages_url, notice: 'Stage was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_stage
#stage = Stage.find(params[:id])
end
def find_project
#project = Project.find(params[:project_id])
end
your edit method is empty, so #responsibility has no content (null), you can put some code for example (from your other method)
def edit
#project = Project.find(params[:id])
#responsibilities = #project.responsibilities
...
end
The issue here is that #responsibilities is not defined in your partial.
You should pass the local variable to the partial like this -
<%= render partial: "form", locals: {responsibilities: # responsibilities} %>
and then you can use responsibilities inside the form partial
More about passing variable to partials

Rails mailer: create object and access the id of the object inside a mailer view template

I'm creating and object inside a controller:
def create
#item = Item.new(item_params)
if #item.save
respond_to do |format|
format.html { redirect_to index_path, notice: "Created"}
format.json { render :'shows/show', status: :created, location: #item }
end
ModelMailer.delay.new_post(#user)
else
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
this is the mailer method:
def new_post(user)
#user = User.find(user.id)
attachments.inline["logo.png"] = File.read("#{Rails.root}/app/assets/images/logo.png")
mail(:to => #follow.email,
:subject => "Created a new post")
end
I would like to add the item.id thats is created to the mailer so I can access it in the email view template. Any ideas on how to implement this?
Just pass it. I don't actually see where you save the record so presumably your create example is incomplete, but once you have that working you can do...
ModelMailer.new_post(#user, #item.id).deliver_later
Then on the mailer
def new_post(user, item_id)
#item_id = item_id
The #item_id will be available in the view.
And to fix your controller create method (which is still wrong), it should be...
def create
#item = Item.new(item_params)
if #item.save
respond_to do |format|
format.html { redirect_to index_path, notice: "Created"}
format.json { render :'shows/show', status: :created, location: #item }
ModelMailer.delay.new_post(#user, #item.id)
end
else
respond_to do |format|
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end

Unknown reason why I'm getting a: undefined method `map' for nil:NilClass error

I'm getting an undefined method `map' for nil:NilClass when I attempt to save my forum.
Here is my jobs_controller.rb:
def new
#job_categories = JobCategory.all.map{|c| [ c.title, c.id ] }
#job = Job.new
end
def edit
#job_categories = JobCategory.all.map{|c| [ c.title, c.id ] }
#job = Job.find(params[:id])
end
def create
#job = Job.new(job_params)
respond_to do |format|
if #job.save
format.html { redirect_to #job, notice: 'Job was successfully created.' }
format.json { render :show, status: :created, location: #job }
else
format.html { render :new }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #job.update(job_params)
format.html { redirect_to #job, notice: 'Job was successfully
updated.' }
format.json { render :show, status: :ok, location: #job }
else
format.html { render :edit }
format.json { render json: #job.errors, status: :unprocessable_entity }
end
end
end
Here is my jobs/_form.html.erb:
<div class="field-group">
<p>Jobs Category</p>
<%= form.select(:job_category_id, options_for_select(#job_categories)) %>
My jobs_categories has it's own controller and model also.
If you need any other information feel free to ask.
My error is happening when I try to submit my form.
#job_categories variable is missing form create and update actions. It causes errors when form renders after an unsuccesfull save - options_for_select tries to call .map on undeclared variable.

How to make not only one object of class ruby?

I need to create array of Events instead of one with same params except event.id . This is code :
def create
#event = Event.new(event_params)
#event.user_id = current_user.id
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: 'Event was successfully created.' }
format.json { render :show, status: :created, location: #event }
else
format.html { render :new }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
How should I do this?
UPD
Event params :
def event_params
params.require(:event).permit(:title, :description, :start_time, :end_time, :repeat)
end
def create
(1..10).each do |i|
params[:event][:user_id] = current_user.id
params[:event][:start_time] = params[:event][:start_time] + 24.hours if i > 1
params[:event][:end_time] = params[:event][:end_time] + 24.hours if i > 1
#event = Event.new(event_params)
#event.save
end
redirect_to events_path
end

Allow admin to post as user in Rails app

I'm building a rails app where users can log on and see a table of their SAT test scores. Users "has_many" scores and Scores "belongs_to" users. Currently it is set up so that the user can post their own scores. What I want is for an admin to post the scores and the user will just see the table on their show page. The "admin" is just a boolean field in users that I set to true for the admins.
Here is the scores controller:
class ScoresController < ApplicationController
def index
#scores = Score.all
end
def show
#score = Score.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #score }
format.js
end
end
def new
#score = Score.new
end
def create
#score = current_user.scores.new(params[:score])
#user = current_user
respond_to do |format|
if #score.save
format.html { redirect_to #score.user, notice: 'Score was successfully created.' }
format.json { render json: #score, status: :created, location: #score }
else
format.html { render action: 'new' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
def update
#score = Score.find(params[:id])
respond_to do |format|
if #score.update(params[:score])
format.html { redirect_to #score.user, notice: 'Score was successfully updated.' }
format.json { render action: 'show', status: :ok, location: #score }
else
format.html { render action: 'edit' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
def edit
#score = Score.find(params[:id])
end
def destroy
#score = Score.find(params[:id])
if #score.present?
#score.destroy
end
redirect_to #score.user
end
end
I know I'd have to change the scores controller so that it didn't rely on current_user to create and edit scores. I'm just not sure how to implement that. Let me know if you need more info! Thanks.
First, you'll need to add a select tag in your view to select which user you want to post as:
- if current_user.is_admin?
= f.select :user_id, options_for_select(User.all.map{ |u| [u.username, u.id] })
- else
= f.hidden_field :user_id, value: current_user.id
Then, on the server-side, we will double-check that current_user is an admin to allow the creation of a Score for another User:
def create
#score = Score.new(params[:score])
if current_user.id != #score.user_id # Someone is trying to create a Score for someone else!
#score.errors.add(:user_id, "You shall not create Score for other users than you, you evil hacker!") unless current_user.is_admin?
end
respond_to do |format|
if #score.save
format.html { redirect_to #score.user, notice: 'Score was successfully created.' }
format.json { render json: #score, status: :created, location: #score }
else
format.html { render action: 'new' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
I omitted the part #user = current_user because usually current_user is a helper method than can be accessed directly in the views, so instead of using #user in the create view, use current_user instead.

Resources