Select avatar from uploaded files - ruby-on-rails

I have carrierwave installed and users can upload photos. How do I set so users don't have to upload a avatar file, but instead can select from their uploaded photos which one will be represented as their avatar? For example when you're on Facebook, click on one of your photos, click the 'Options' link and it shows you 'Make profile picture'. That image will then become your avatar, or picture that is used throughout Facebook. I am looking for the same thing.
Gallery Controller:
def index
#galleries = Gallery.all
end
def show
#gallery = Gallery.find(id_params)
end
def new
#gallery = Gallery.new
end
def create
#gallery = Gallery.new(gallery_params)
if #gallery.save
flash[:notice] = "Created gallery."
redirect_to #gallery
else
render :action => 'new'
end
end
def edit
#gallery = Gallery.find(id_params)
end
def update
#gallery = Gallery.find(id_params)
if #gallery.update_attributes(gallery_params)
flash[:notice] = "Updated gallery."
redirect_to gallery_url
else
render :action => 'edit'
end
end
def destroy
#gallery = Gallery.find(id_params)
#gallery.destroy
flash[:notice] = "Gallery deleted."
redirect_to galleries_url
end
private
def gallery_params
params.require(:user).permit(:name)
end
def id_params
params.require(:id).permit(:name)
end
end
Photo Controller:
def new
#photo = Photo.new
end
def create
#photo = Photo.new(params[:photo])
#photo.user = current_user
if #photo.save
flash[:notice] = "Successfully created photos."
redirect_to :back
else
render :action => 'new'
end
end
def edit
#photo = Photo.find(params[:id])
end
def update
#photo = Photo.find(params[:id])
if #photo.update_attributes(paramas[:photo])
flash[:notice] = "Successfully updated photo."
redirect_to #photo.gallery
else
render :action => 'edit'
end
end
def destroy
#photo = Photo.find(params[:id])
#photo.destroy
flash[:notice] = "Successfully destroyed photo."
redirect_to #photo.gallery
end
end

Here's an example of what I might do
class UserAvatarController < ApplicationController
def edit
#gallery = current_user.gallery
# render gallery of photos for user to choose
end
def update
if params[:photo_id].present?
current_user.update_attributes avatar_id: params[:photo_id]
else
flash[:error] = "No photo selected"
render action: "edit"
end
end
end

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

No route matches, missing required keys

I'm currently working on rails 5 project in which I want to add a passenger to a transportation. In the in the passengers controller index action I set transportation to be search by the params id. But it returns nil even though it has been created.
Here are the routes:
user_protest_transportation_passengers GET /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers(.:format) passengers#index
POST /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers(.:format) passengers#create
new_user_protest_transportation_passenger GET /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/new(.:format) passengers#new
edit_user_protest_transportation_passenger GET /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/:id/edit(.:format) passengers#edit
user_protest_transportation_passenger GET /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/:id(.:format) passengers#show
PATCH /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/:id(.:format) passengers#update
PUT /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/:id(.:format) passengers#update
DELETE /users/:user_id/protests/:protest_id/transportations/:transportation_id/passengers/:id(.:format) passengers#destroy
user_protest_transportations GET /users/:user_id/protests/:protest_id/transportations(.:format) transportations#index
POST /users/:user_id/protests/:protest_id/transportations(.:format)
Here is the link:
<div class="card">
<div class="card-block">
<h3 class="card-title">Need A Ride?</h3>
<p class="card-text">Find people near you willing to share a seat who are coming to the event. We are all in this together!.</p>
<%= link_to 'Get A Ride', new_user_protest_transportation_passenger_path(#user, #protest, #transportation), class: "btn btn-primary" %>
</div>
</div>
Here is the passengers controller:
class PassengersController < ApplicationController
def index
#transportation = Transportation.find(params[:transportation_id])
end
def new
end
def create
#passenger = Passenger.new(passenger_params)
#user = User.find(current_user.id)
#transportation = Transportation.find(params[:transportation_id])
#driver = User.find(#transportation.transporter_id)
#protest = Protest.find(#transportation.destination_id)
#transportations = Transportation.where(destination_id: #protest.id)
has_ride = false
#transportations.each do |transportation|
passenger = Passenger.find_by user_id: current_user.id
unless (passenger.nil?)
has_ride = true
end
end
if has_ride
redirect_to protests_path, notice: "You already have a ride."
return
end
respond_to do |format|
if #passenger.save
format.html { redirect_to user_protest_transportation_passenger_path(id: #passenger.id), notice: 'Passenger was successfully created.' }
else
format.html { render :new }
end
end
end
def show
#driver = get_driver
if #driver
#transportation = Transportation.where(transporter_id: #driver.id).first!
#protest = Protest.find(#transportation.destination_id)
end
end
def edit
end
def update
end
def destroy
#passenger = Passenger.find_by(user_id: params[:user_id], transportation_id: params[:transportation_id])
if #passenger
#passenger.destroy
redirect_to user_protests_path, notice: 'Ride was canceled.'
else
redirect_to user_protest_transportations_path, notice: 'Error: the passenger record failed to delete.'
end
end
private
def get_driver
driver = nil
p = Passenger.find_by(user_id: current_user.id, transportation_id: params[:transportation_id])
t = Transportation.find(params[:transportation_id])
driver = User.find(t.transporter_id)
end
def passenger_params
params.permit(:user_id, :transportation_id)
end
end
I am trying to get the transportation id in the params, I tried find with session[transportation_id] but didn't seem to work.
protest controller:
class ProtestsController < ApplicationController
def index
#protests = Protest.all
end
def show
#protest = Protest.find(params[:id])
#user = current_user
end
def new
#protest = Protest.new
end
def edit
#protest = Protest.find(params[:id])
end
def create
#protest = Protest.new(protest_params)
#protest.creator = current_user
respond_to do |format|
if #protest.save
format.html { redirect_to #protest, notice: 'Protest was successfully created.' }
else
format.html { render :new }
end
end
end
def update
#protest = Protest.find(params[:id])
respond_to do |format|
if #protest.update(protest_params)
format.html { redirect_to #protest, notice: 'Protest was successfully updated.' }
else
format.html {render :edit }
end
end
end
def destroy
#protest = Protest.find(params[:id])
#protest.destroy
redirect_to protests_path
end
private
def protest_params
params.require(:protest).permit(:name, :description, :location, :starts_at, :creator, :image)
end
end

The action 'destory' could not be found in controller

I think I'm losing it. I can't figure out why a simple destroy link wont work all of a sudden.
I'm getting this error:
AbstractController::ActionNotFound at /plans/v41w74v2
The action 'destroy' could not be found for PlansController
Plan Controller:
class PlansController < ApplicationController
before_filter :authenticate_user!
def index
#plans = Plan.all
end
def new
#plan = Plan.new
end
def create
#plan = Plan.new(plan_params)
if #plan.save
if #plan.trips.empty?
#possible = #plan.group.trips
render "add_trips"
else
redirect_to plans_path, notice: "Plan successfully created"
end
else
render "new"
end
end
def show
#plan = Plan.find_by_unique_identifier(params[:id])
end
def edit
#plan = Plan.find_by_unique_identifier(params[:id])
#group = #plan.group
#possible = #plan.group.trips
render "add_trips"
end
def update
#plan = Plan.find_by_unique_identifier(params[:id])
if #plan.update_attributes(plan_params)
redirect_to plans_path, notice: "Plan successfully updated!"
else
render "edit"
end
end
def add_trips
#plan = Plan.find_by_unique_identifier(params[:id])
trip.each.update_attributes(plan_id: #plan.id)
redirect_to plans_path, notice: "Trips added to plan"
end
def destory
#plan = Plan.find_by_unique_identifier(params[:id])
#plan.destroy
end
Plan show View:
<%= button_to "Delete", #plan, method: :delete, data: { confirm: "Are you sure you want to delete this plan?"} %>
What am I doing wrong?
Yep. You've got a typo. destory.

Rails polymorphic commenting with permalink/token urls

In my app I have a commenting system that's largely based off of this railscast. Now in my models I'm changing the to_param to a random string so the id isn't in the url. But then that breaks commenting.
status.rb
class Status < ActiveRecord::Base
attr_accessible :content, :member_id, :document_attributes, :permalink
belongs_to :member
belongs_to :document
has_many :comments, as: :commentable, dependent: :destroy
before_create :make_it_permalink
accepts_nested_attributes_for :document
def to_param
permalink
end
private
def make_it_permalink
# this can create permalink with random 12 digit alphanumeric
self.permalink = SecureRandom.hex(12)
end
end
statuses_controller.rb
class StatusesController < ApplicationController
before_filter :authenticate_member!, only: [:index, :new, :create, :destroy]
before_filter :find_member
rescue_from ActiveRecord::RecordNotFound do
render file: 'public/404', status: 404, formats: [:html]
end
def index
#statuses = Status.order('created_at desc').page(params[:page]).per_page(21)
respond_to do |format|
format.html # index.html.erb
format.js
end
end
def show
#status = Status.find_by_permalink(params[:id])
#commentable = #status
#comments = #commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
#comment = #commentable.comments.new
respond_to do |format|
format.html # show.html.erb
format.json { redirect_to profile_path(current_member) }
end
end
def new
#status = Status.new
#status.build_document
respond_to do |format|
format.html # new.html.erb
format.json { render json: #status }
format.js
end
end
def create
#status = current_member.statuses.new(params[:status])
respond_to do |format|
if #status.save
#activity = current_member.create_activity(#status, 'created')
format.html { redirect_to :back }
format.json
format.js
else
format.html { redirect_to profile_path(current_member), alert: 'Post wasn\'t created. Please try again and ensure image attchments are under 10Mbs.' }
format.json { render json: #status.errors, status: :unprocessable_entity }
format.js
end
end
end
def destroy
#status = current_member.statuses.find(params[:id])
#activity = Activity.find_by_targetable_id(params[:id])
#commentable = #status
#comments = #commentable.comments
if #activity
#activity.destroy
end
if #comments
#comments.destroy
end
#status.destroy
respond_to do |format|
format.html { redirect_to profile_path(current_member) }
format.json { head :no_content }
end
end
private
def find_member
#member = Member.find_by_user_name(params[:user_name])
end
def find_status
#status = current_member.statuses.find_by_permalink(params[:id])
end
end
comments_controller.rb
class CommentsController < ApplicationController
before_filter :authenticate_member!
before_filter :load_commentable
before_filter :find_member
def index
redirect_to root_path
end
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(params[:comment])
#comments = #commentable.comments.order('created_at desc').page(params[:page]).per_page(15)
#comment.member = current_member
respond_to do |format|
if #comment.save
format.html { redirect_to :back }
format.json
format.js
else
format.html { redirect_to :back }
format.json
format.js
end
end
end
def destroy
#comment = Comment.find(params[:id])
respond_to do |format|
if #comment.member == current_member || #commentable.member == current_member
#comment.destroy
format.html { redirect_to :back }
format.json
format.js
else
format.html { redirect_to :back, alert: 'You can\'t delete this comment.' }
format.json
format.js
end
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, Project, Event, Listing].detect { |c| params["#{c.name.underscore}_id"] }
#commentable = klass.find(params["#{klass.name.underscore}_id"])
end
#def load_commentable
# #commentable = params[:commentable_type].camelize.constantize.find(params[:commentable_id])
#end
def find_member
#member = Member.find_by_user_name(params[:user_name])
end
end
The problem lies in the load_commentable method in the comments_controller. I've tried a couple different variations of the method but the second one works best for my app and it was working when the url's had their id's in them. But since I overwrote the to_param to use my random permalink commenting stopped working because it's trying to find theid where it equals the permalink. Since it seems to try to find the id through the url, how do I pass the the actual id and not the permalink or how do I find commentable by it's permalink instead of id?
It's hard to tell if your param will always be the value of id or always be the permalink, or will sometimes be an id and sometimes a permalink.
If it will always be a permalink, then do:
#commentable = klass.find_by_permalink(params["#{klass.name.underscore}_id"])
instead of
#commentable = klass.find(params["#{klass.name.underscore}_id"])
If it is sometimes id and sometimes other, then you will need make logic to determine which is needed based on the class.

Rails: Trying to better understand respond_with syntax

I am refactoring some older code and am trying to get a better grasp on the respond_with syntax...
Here is my controller:
class VideosController < ApplicationController
authorize_resource
before_filter :authenticate_user!
respond_to :json, :js, :html
def index
#video = Video.new(athlete_id: current_user.id, sport_id: current_athlete_sport.id)
#videos = current_user.videos_for_sport(current_athlete_sport).order("date DESC")
respond_with #videos
end
def create
#athlete = Athlete.find(params[:video][:athlete_id])
#video = Video.new(params[:video])
if #athlete.can_add_another_video? && #video.save
flash[:notice] = "Successfully created"
PandaWorker.perform_async(#video.id)
log_activity(#video.logging_information)
else
flash[:notice] = #video.errors.full_messages.to_sentence
end
respond_with #video, location: edit_videos_path
end
def update
#video = Video.find(params[:id])
#athlete = Athlete.find(#video.athlete_id)
update_featured = params[:video][:featured].eql?("1") && !current_user.featured_video.blank? && current_user.featured_video.id != #video.id
current_user.featured_video.update_attribute(:featured, false) if update_featured
if #video.update_attributes(params[:video])
flash[:notice] = "Successfully Updated!"
log_activity(#video.logging_information)
else
flash[:notice] = #video.errors.full_messages.to_sentence
end
respond_with #video, location: edit_videos_path do |format|
format.json { render json: { message: flash[:notice], reload: update_featured } }
end
end
def show
#video = Video.find(params[:id])
render layout: false
end
def destroy
#video = Video.find(params[:id])
#athlete = Athlete.find(#video.athlete_id)
if #video.destroy
flash[:notice] = 'Video was successfully destroyed'
log_activity(#video.logging_information)
else
flash[:notice] = 'There was a problem destroying that video'
end
respond_with #athlete, location: edit_videos_path
end
def rotate
#video = Video.find(params[:id])
#encoding = #video.encode(params[:direction])
if #video.update_attributes(thumbnail_url: #encoding.screenshots.first, mp4_video_url: #encoding.url)
flash[:notice] = "Your video was successfully rotated"
else
flash[:notice] = "There was a problem rotating that video"
end
respond_with #video, location: edit_videos_path
end
end
Just curious to know if I doing things the right way, more so in the update/create methods
It's really just a convenience when your controller can respond to a variety of format requests.
This is a pretty good article describing it.

Resources