(post updated down below)
My issue: Is that I need a separate update action for the different params in my controller. I need a general update actions for params (minus params in the separate update actions/methods), an update action for :video, and an update action for :order_status
Question: How can I efficiently accomplish having multiple update actions in my controller?
Here is an idea of what I want, and it doesn't work:
def charge_update
respond_to do |format|
#amount = (#order.order_price).to_i * 100
#amount_seller = (#order.order_price).to_i * 75
if #order.update(order_charge)
if user_signed_in? && user.seller?
charge = Stripe::Charge.create({
:amount => (#order.order_price).to_i * 100,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => #order.stripe_customer_token,
:destination => {
:amount => #amount_seller ,
:account => (#order.seller.stripe_token),
}
})
#order.order_status = "charged"
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
def cancel_update
respond_to do |format|
if #order.cancel_update(order_update)
if user_signed_in?
if #order.order_status = "cancelled"
format.html { redirect_to #order, notice: 'Order was successfully cancelled.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
end
def update
respond_to do |format|
if #order.update( order_params.except(:order_status) )
if user_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
private
def order_params
params.require(:order).permit(:name, :email, :image,:description)
end
def order_status
params.require(:order).permit(:order_status)
end
def order_charge
params.require(:order).permit(:video)
end
...
My issues with what I need to accomplish:
I want a separate action for when an order_status is changed, for each value. Most importantly, I want a certain message to be displayed depending on the value that the order_status column is changed to.
Most important issue:
I need a separate update action for charging customers. This is most important because i can't just have a customer being charged when someone updates a name, or when a seller updates an order_status, etc.
I'm doing something wrong or i need to set up the routes to have the ability to allow multiple update actions?
So how i can separate the updates and params?
UPDATE
I embedded the update methods into the one original method like so...
but i have one issue now, the message notices don't appear correct to the update param. The "Order was successfully updated" appears, which isn't the customized one for when i upload a video or change the ordeR_status column
def update
respond_to do |format|
if params["order_status"]
if user_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully order_status.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
if params["video"]
#amount = (#order.order_price).to_i * 100
#amount_seller = (#order.order_price).to_i * 75
if #order.update(order_charge)
if user_signed_in? && user.seller?
charge = Stripe::Charge.create({
:amount => (#order.order_price).to_i * 100,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => #order.stripe_customer_token,
:destination => {
:amount => #amount_seller ,
:account => (#order.seller.stripe_token),
}
})
#order.order_status = "charged"
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
if #order.update(order_params)
if user_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
So I have two issues now:
The customized messages don't show
and under the :video param update, I want the order status to change the "charged", but what i currently have doesn't do it
Anyone have any ideas on how to improve this?
This seems to have solved it so far. :::
def update
respond_to do |format|
if #order.update(order_status)
if user_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully order_status.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
if #order.update(order_charge)
#amount = (#order.order_price).to_i * 100
#amount_seller = (#order.order_price).to_i * 75
if #order.update(order_charge)
if current_user.seller?
charge = Stripe::Charge.create({
:amount => (#order.order_price).to_i * 100,
:description => 'Rails Stripe customer',
:currency => 'usd',
:customer => #order.stripe_customer_token,
:destination => {
:amount => #amount_seller ,
:account => (#order.seller.stripe_token),
}
})
#order.order_status = "charged"
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully uploaded.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
if #order.update(order_params)
if user_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
if buyer_signed_in?
format.html { redirect_to ([#user, #order]), notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
end
private
def order_params
params.require(:order).permit(:name, :email, :image, :video, :description)
end
def order_status
params.require(:order).permit(:order_status)
end
def order_charge
params.require(:order).permit(:video)
end
end
If anyone sees this and thinks they have a better way, please let me know. I'm not sure how convenient or efficient this may be, (embedding all into one method, etc.) but it seems to work. My only issue is that
When i change order_status to cancel, no message appears but it works.
when i change fill in the video param, the order_status message appears. Which i understand but i don't understand why it won't appear when i change the status to cancel - and btw, cancel is a enum of "2".
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.
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'
I have a form with a time_select input field. I am manipulating the data in the controller and storing as integer.
In the view
<%= f.label :duration %>
<%= f.time_select :duration, {}, { class: 'form-control time-select' }%>
In the controller
def create
#task = Task.new(task_params)
#hours = (params[:task]['duration(4i)']).to_i
#minutes = (params[:task]['duration(5i)']).to_i
#task.duration = #hours*60 + #minutes
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
def edit
#task = Task.find(params[:id])
#task['duration(4i)'] = (#task.duration / 60).to_s
#task['duration(5i)'] = (#task.duration % 60).to_s
end
It works for the create, but not for the edit. I am getting
can't write unknown attribute duration(4i)
I'm building a site where a link to fill a new form can be clicked from an Event show page
<%= link_to 'Be a Contestant', new_form_path(:event_id => #event.id)%>
This creates a link like
http://localhost:3000/forms/new?event_id=2
Now if the form is filled with an error, when submitted, it returns an error
Couldn't find Event with 'id'=""
So I decided to use the request.referrer to redirect back to the previous page but it doesn't list the errors as use this method
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to request.referrer }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
I also tried this but to no avail.
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { redirect_to new_form_path(:event_id => request.referrer.params[:event_id]) }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end
What you probably really need to do is to add a hidden field event_id to the form because I'm betting that event_id doesn't get propagated from the #new to the #create action.
See here for more information on hidden_field_tag
You usually just render the edit view when there was an error in create:
def create
#form = Form.new(form_params)
respond_to do |format|
if #form.save
format.html { redirect_to #form, notice: 'Form was successfully created.' }
format.json { render :show, status: :created, location: #form }
else
format.html { render :edit, alert: 'Error creating ...' }
format.json { render json: #form.errors, status: :unprocessable_entity }
end
end
end