Rails 4: how to check if an instance has been deleted - ruby-on-rails

In our Rails app, we have a CalendarsController:
class CalendarsController < ApplicationController
def create
#calendar = current_user.calendars.create(calendar_params)
current_user.add_calendar_and_role(#calendar.id, 'Owner')
if #calendar.save
current_user.total_calendar_count += 1
current_user.owned_calendar_count += 1
current_user.save
flash[:success] = "Calendar created!"
redirect_to dashboard_path
else
render 'static_pages/home'
end
end
def show
#calendar = Calendar.find(params[:id])
#posts = #calendar.posts
#post = Post.new
end
def index
end
def edit
end
def destroy
Calendar.find(params[:id]).destroy
flash[:success] = "Calendar deleted"
redirect_to dashboard_path
end
private
def calendar_params
params.require(:calendar).permit(:name)
end
end
In the create action, when a new #calendar is created, we run #calendar.save to check if the new instance has actually been created, and then perform some actions.
We would like to implement a similar process in our destroy action.
We are thinking of updating the destroy method as follows:
def destroy
#calendar = Calendar.find(params[:id])
#calendar.destroy
if #calendar.delete
flash[:success] = "Calendar deleted"
current_user.total_calendar_count -= 1
if #calendar.administrations.role == "Owner"
current_user.owned_calendar_count -= 1
end
end
redirect_to dashboard_path
end
Is the syntax of this code correct, in particular if #calendar.delete and if #calendar.administrations.role == "Owner"?
And, most importantly, would the code of this destroy action make sense?

Did you think about using the persisted? method
#calendar.destroy
unless #calendar.persisted?
... some code here ....
end

I believe it would be more like:
def destroy
#calendar = Calendar.find(params[:id])
calendar_admin_role = #calendar.administrations.role
if #calendar.destroy
flash[:success] = "Calendar deleted"
current_user.total_calendar_count -= 1
if calendar_admin_role == "Owner"
current_user.owned_calendar_count -= 1
end
end
redirect_to dashboard_path
end
But this is off the top of my head after a long day at work so could be wrong.

Related

Is it possible to chain strong parameters in a Rails controller

I'm currently doing this
class DetailsController < ApplicationController
def create
#detail = Detail.new(params.require(:detail).permit(:user_id, :note))
if #detail.save
redirect_to #detail
else
render 'new'
end
end
def update
#detail = Detail.find(params[:id])
if #detail.update(detail_params)
redirect_to #detail
else
render 'edit'
end
end
private
def detail_params
params.require(:detail).permit(:note)
end
end
Is it possible too chain strong parameters in Rails? I tried doing this but it didn't work
class DetailsController < ApplicationController
def create
#detail = Detail.new(detail_params.permit(:user_id))
if #detail.save
redirect_to #detail
else
render 'new'
end
end
def update
#detail = Detail.find(params[:id])
if #detail.update(detail_params)
redirect_to #detail
else
render 'edit'
end
end
private
def detail_params
params.require(:detail).permit(:note)
end
end
To DRY things up I have used the tap method and done something like this...
def detail_params(is_create = false)
params.require(:detail).permit(:note).tap do |p|
p[:user_id] = current_user.id if is_create
end
end
def create
#detail = Detail.new(detail_params(true))
if #detail.save
redirect_to #detail
else
render 'new'
end
end
def update
#detail = Detail.find(params[:id])
if #detail.update(detail_params)
redirect_to #detail
else
render 'edit'
end
end
To just have different sets of parameters, this works...
def detail_params(is_create = false)
permitted = [:note]
permitted << :user_id if is_create
params.require(:detail).permit(permitted)
end

Rails 5: Old value isn't updating in database

I'm currently trying to store an updated value in the database.
The process is the following, a user chooses to buy 3 bottles, the stock goes down by -3. The stock is set within the Wines Controller and then displayed in the reservations controller for the user
The current problem is that for each new reservation, the stock get's reset in the reservations controller, since the stock isn't updating in the wines controller.
Here lays the problem:
#reservation.in_stock = wine.in_stock - #reservation.bottle
Here is my full Reservations Controller:
class ReservationsController < ApplicationController
before_action :authenticate_user!
before_action :set_reservation, only: [:approve, :decline]
def create
wine = Wine.find(params[:wine_id])
if current_user == wine.user
flash[:alert] = "Du kannst nicht deinen eigenen Wein kaufen!"
else
start_date = Date.parse(reservation_params[:start_date])
#reservation = current_user.reservations.build(reservation_params)
#reservation.wine = wine
#reservation.price = wine.price
#reservation.in_stock = wine.in_stock - #reservation.bottle
#reservation.total = wine.price * #reservation.bottle
# #reservation.save
if #reservation.save
if wine.Reservieren?
flash[:notice] = "Anfrage versendet!"
else
#reservation.Bearbeitung!
flash[:notice] = "Eroflgreich bestellt!"
end
else
flash[:alert] = "Can't make a reservation!"
end
end
redirect_to wine
end
def your_orders
#orders = current_user.reservations.order(start_date: :asc)
end
def your_reservations
#wines = current_user.wines
redirect_to root_path unless current_user.admin == true
#count = Reservation.count(:all)
#total = Reservation.sum(:total)
end
def your_upcoming_reservations
#wines = current_user.wines
redirect_to root_path unless current_user.admin == true
end
def approve
#reservation.Versendet!
redirect_to your_reservations_path
redirect_to root_path unless current_user.admin == true
end
def decline
#reservation.Abgelehnt!
redirect_to your_reservations_path
redirect_to root_path unless current_user.admin == true
end
# Each Order Details
def order_details
#orders = current_user.reservations.order(start_date: :asc)
end
private
def set_reservation
#reservation = Reservation.find(params[:id])
end
def set_stock
#reservation.in_stock = wine.in_stock
end
def reservation_params
params.require(:reservation).permit(:start_date, :bottle, :in_stock)
end
end

Resque job undefined method 'current_user'

It's my first attempt at Resque and doing background jobs, and I'm kind of stuck.
I have two issues at hand.
It gives me the error
undefined local variable or method `current_user'
I am not sure if what I am pushing to the worker is indeed the most correct thing.
Here is my code:
schedules_controller.rb
def trial
#schedule = current_user.schedules.new
if #schedule.save
user = User.find(params[:id])
#client = Buffer::Client.new(user.token)
Resque.enqueue(ScheduleTweets, #client)
#schedule.update_attribute(:trial, true)
flash[:notice] = "success"
redirect_to :back
else
flash[:alert] = "Try again."
redirect_to :back
end
end
and the worker:
apps/workers/schedule_tweets.rb
class ScheduleTweets
#queue = :schedules_queue
def self.perform(client)
user = User.find(params[:id])
client = Buffer::Client.new(user.token)
#list = List.first(6)
#profiles = client.profiles
#profile_ids = profiles.map(&:id)
#list.each do |list|
client.create_update(body: {text: "#{list.text}", profile_ids: #profile_ids })
end
end
end
end
my thought process is that the client is the core of the entire process and should thus be the one. However #profile_ids also contains anywhere from 1-5 values.
When I run the task I get the undefined local variable or method 'current_user'. How do I fix that, also am I doing it right by choosing the #client as the thing to add?
Try this
schedules_controller.rb
def trial
#schedule = current_user.schedules.new
if #schedule.save
user = User.find(params[:id])
#client = Buffer::Client.new(user.token)
Resque.enqueue(ScheduleTweets, user.id)
#schedule.update_attribute(:trial, true)
flash[:notice] = "success"
redirect_to :back
else
flash[:alert] = "Try again."
redirect_to :back
end
end
and the worker:
apps/workers/schedule_tweets.rb
class ScheduleTweets
#queue = :schedules_queue
def self.perform(user_id)
user = User.find(user_id)
client = Buffer::Client.new(user.token)
#list = List.first(6)
#profiles = client.profiles
#profile_ids = #profiles.map(&:id)
#list.each do |list|
client.create_update(body: {text: "#{list.text}", profile_ids: #profile_ids })
end
end
end

Rails polymorphic comments scoping delete action

I've implemented polymorphic commenting based off the Ryan Bates Railscast and everything is working correctly so far, but I'm trying to scope the delete action so that only the owner of the comment can delete their own comments and the owner of the commentable can delete any comment. I'm not sure how to make this happen.
Any ideas?
Here's my CommentsController:
class CommentsController < ApplicationController
before_filter :authenticate_member!
before_filter :load_commentable
def index
#comments = #commentable.comments
#comment = #commentable.comments.new
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(params[:comment])
#comment.member = current_member
if #comment.save
redirect_to :back
else
render :new
end
end
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
if #comment.destroy
redirect_to :back
else
format.html { redirect_to :back, alert: 'You can\'t delete this comment.' }
end
end
private
# def load_commentable
# resource, id = request.path.split('/')[1,2] # photos/1/
# #commentable = resource.singularize.classify.constantize.find(id)
# Photo.find(1)
# end
# alternative option:
def load_commentable
klass = [Status, Medium].detect { |c| params["#{c.name.underscore}_id"] }
#commentable = klass.find(params["#{klass.name.underscore}_id"])
end
end
You could set up your destroy method as follows:
def destroy
#comment = Comment.find(params[:id])
if #comment.user == current_user
#comment.destroy
format.html { redirect_to :back, alert: "Comment Successfully destroyed" }
else
format.html { redirect_to :back, alert: 'You can\'t delete this comment.' }
end
end
If you want to allow your admin to delete any comments, you can change
if #comment.user == current_user
to
if #comment.user == current_user || current_user.admin?

refactoring code in rails controller

i have two actions in my controller
def up_vote
lesson = Lesson.find(params[:id])
current_user.up_vote!(lesson)
flash[:message] = 'Thanks for voting!'
redirect_to lesson_path(lesson)
end
def down_vote
lesson = Lesson.find(params[:id])
current_user.down_vote!(lesson)
flash[:message] = 'Thanks for voting!'
redirect_to lesson_path(lesson)
end
i was wondering what would be a good way to refactor this (keeping DRY in mind)? i read online that i shouldn't be trying to abuse the before_filter. what else could i use then? thanks!
def vote_up
vote(:up)
end
def vote_down
vote(:down)
end
protected
def vote(direction)
lesson = Lesson.find(params[:id])
current_user.send :"#{direction}_vote!",lesson
flash[:message] = 'Thanks for voting!'
redirect_to lesson_path(lesson)
end
Well most obviously would be to use a single method which takes an up_or_down parameter.
def vote(up_or_down)
lesson = Lesson.find(params[:id])
if up_or_down.eql? "up"
current_user.up_vote!(lesson)
elsif up_or_down.eql? "down"
current_user.down_vote!(lesson)
else
# send an error message or just return
end
flash[:message] = 'Thanks for voting!'
redirect_to lesson_path(lesson)
end

Resources