Question

I have the CarrierWave gem installed. There are no galleries, as I have it setup so that photos belong to a user not a gallery.

I added a avatar column to the Photos table. The other columns are: id, created_at, updated_at, image, name, user_id

The question is how do I set a action so the users can click 'Make Profile Image' and it will make changes to the avatar column? This should be done by either clicking on the thumbnail version of the image or having text overlay.

A example of what I mean:

User Z uploads four photos to their profile. User Z visits their profile and selects one of their uploaded photos to be their Profile image (avatar).

   class PhotosController < ApplicationController

  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 resize(width, height, gravity = 'Center')
    manipulate! do |img|
      img.combine_options do |cmd|
        cmd.resize "#{width}"
        if img[:width] < img[:height]
          cmd.gravity gravity
          cmd.background "rgba(255,255,255,0.0)"
          cmd.extent "#{width}x#{height}"
        end
      end
      img = yield(img) if block_given?
      img
    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

  def avatar
    @photo = Photo.find params[:photo_id]
    current_user.default_photo = @photo
    redirect_to '/profile'
  end
end

view (shows thumb photos on profile):

<div class="parent-container">
    <% @user.photos.each do |photo| %>
        <%= link_to image_tag(photo.image_url(:thumb)), photo.image_url%>
<% end %></div></p>
Was it helpful?

Solution

You have a User and a User has Photos, of which one could be the Avatar...

What I would recommend you do is have a avatar_id on User, and a relationship like the following:

class User < ActiveRecord::Base
  has_many :photos
  belongs_to :avatar, class_name: 'Photo'
end

Then in your controller, if you preference is to add a new action, it would be like so:

class PhotosController < ApplicationController
  ...

  def avatar
    if current_user.update_attribute(:avatar_id, params[:id])
      #set flash success
    else
      #set flash fail
    end
    redirect_to(current_user) # However you plan to handle this...
  end

  ...
end

(The reason why you might want to use a new controller is to maintain "DRY")

Which I assume you would have a member route like so:

resources :photos do
  member do
    post :avatar
  end
end

And an action like so:

button_to('Set as Avatar', [:avatar, @photo])

Then you reference it in the view like so:

@user.avatar.image_url(:thumb)

That should do the trick.

OTHER TIPS

You could do something like this so you render the gallery of available photos and allow the user to select one for their DP/Avatar/Profile picture

class UserAvatarController < ApplicationController

def edit
@gallery = current_user.gallery
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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top