Having some trouble trying to get this to work in Rails 4 -
http://railscasts.com/episodes/182-cropping-images?view=comments
As per one of the questions in the comments: using the after_update callback to update the images, it ran into an infinite loop
Apparently the fix is to put #user.avatar.reprocess! directly in the controller instead. However I am not sure where exactly in the controller this should go. And if I'm putting this in the right place is it going to work with rails 4?
I have tried the following with no luck:
def create
#user = User.new(user_params)
if #user.save
if user_params[:avatar].blank?
#user.avatar.reprocess!
flash[:notice] = "Successfully created user."
redirect_to #user
else
render :action => "crop"
end
else
render 'new'
end
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
if user_params[:avatar].blank?
#user.avatar.reprocess!
flash[:notice] = "Successfully updated user."
redirect_to #user
else
render :action => "crop"
end
else
render :action => 'edit'
end
end
my update action:
def update
#user=User.find(params[:id])
#user.update_attributes(user_params)
if #user.cropping?
#user.profile_image.reprocess!
end
if #user.save!
redirect_to user_path(#user)
end
end
and my cropper.rb
module Paperclip
class Cropper < Thumbnail
def transformation_command
if crop_command
crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ') # super returns an array like this: ["-resize", "100x", "-crop", "100x100+0+0", "+repage"]
else
super
end
end
def crop_command
target = #attachment.instance
if target.cropping?
["-crop", "#{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"]
end
end
end
end
This has worked for me nicely.
You can read more about this issue via Paperclip - Issue #866.
User jgarber describes a hack to workaround it, using the following:
def reprocess_photo
photo.assign(photo)
photo.save
end
Related
This is my ArticleController
def new
#article = Article.new
end
def create
#render plain: params[:article].inspect
#article = Article.new(super_params)
if #article.save
flash[:notice] = "Article has been created"
redirect_to article_path(#article)
else
render 'new'
end
end
def super_params
params.require(:article).permit(:title, :description)
end
def show
#article = Article.find_by( params[:id] )
end
The main problem is that whenever i do: articles/2 or 5 or 6 i get the same article which was created as first. In database records are good i have only this problem with render it.
I know, i did:
find_by
Instead of
find
Sory for trouble...
I have a prompt asking to write my up_vote and down_vote methods in only two lines using 'redirect_to' and the 'update_vote!' method as presented below. Implementing redirect_to is easy enough, but I'm not quite sure how to write my up/down_vote methods concisely using the existing 'update_vote!' method. Any help is appreciated.
class VotesController < ApplicationController
before_action :load_post_and_vote
def up_vote
if #vote
#vote.update_attribute(:value, 1)
else
#vote = current_user.votes.create(value: 1, post: #post)
end
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
def down_vote
if #vote
#vote.update_attribute(:value, -1)
else
#vote = current_user.votes.create(value: -1, post: #post)
end
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
private
def load_post_and_vote
#post = Post.find(params[:post_id])
#vote = #post.votes.where(user_id: current_user.id).first
end
def update_vote!(new_value)
if #vote
authorize #vote, :update?
#vote.update_attribute(:value, new_value)
else
#vote = current_user.votes.build(value: new_value, post: #post)
authorize #vote, :create
#vote.save
end
end
end
You should invoke the update_vote! method. How about:
def up_vote
update_vote!(1)
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
def down_vote
update_vote!(-1)
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
Also your method can be re-written as :
def update_vote!(new_value)
Vote.find_or_create_by post: #post do |v|
authorize v, :update?
v.user_id = current_user.id
v.value = new_value
v.save!
end
end
Read find_or_create_by.
seems that answer was easy enough =]
def up_vote
update_vote(1)
redirect_to :back
end
def down_vote
update_vote(-1)
redirect_to :back
end
I keep getting a variety of error while trying to create and show errors in a simple Rails blog I'm trying to create.Let me know if you see anything obvious or if you need me to post more code as I've tried a number of things but to no avail. Thanks
The browser is giving me this error
Couldn't find User without an ID
in my "logged_in?" method which shows
def logged_in?
#current_user ||= User.find(session[:user_id])
end
Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
flash[:success] = "You are logged in"
redirect_to root_path
else
render action: 'new'
flash[:error] = "There was a problem logging in. Please check your email and password"
end
end
end
def index
#users = User.all
end
def show
end
def new
#user = User.new
end
def edit
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
flash[:notice] = "You have registered, please login"
redirect_to login_path
else
render :new
end
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
Articles Controller
class ArticlesController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
def new
#article = Article.new
end
def index
#article = Article.all
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def edit
#article = Article.find(params[:id])
end
def update
#article = Article.find(params[:id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def show
#article = Article.find(params[:id])
end
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text, :image)
end
end
Application Helper
module ApplicationHelper
def logged_in?
#current_user ||= User.find(session[:user_id])
end
end
The problem you're facing is that session[:user_id] is nil. Usually a method which sets current user is called current_user. The logged_in? is not a good name for a method setting an user instance, because one would expect that a method ending with a question mark would return a true or false. And not an user instance.
Also, setting the current user is usually done with a before_filter. Additionally, you want to skip such before filter for action where you're setting the current user (i.e the current_user doesn't exist yet)
Finally, I would rather fail gracefully, if user is not found. You can achieve this by changing your code to User.find_by_id(session[:user_id])
While the user is not loggued, session[:user_id] is nil, and so User.find(session[:user_id]) generates the error. The method should be like this:
def logged_in?
#current_user ||= User.find(session[:user_id]) if session[:user_id].present?
end
Why would the logged_in? helper method try to assign a value to #current_user? I think that is a bad logic, it should just return a boolean result without modifying such a central instance. This is a proper way to do that:
def logged_in?
#current_user.nil? ? false : true
end
The responsibility of setting the #current_user falls to a method that you should place in application_controller.rb and make it a before_action so that it's executed before any controller action is triggered, that is:
# app/controllers/applicaton_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
before_action :authenticate_user
# Your actions here
..
..
#
private
def authenticate_user
#current_user ||= User.find(session[:user_id]) if session[:user_id].present?
end
end
My question is actually fairly simple, how do I make a create action which checks if a user is logged in, and if she/he is then redirect to the dashboard instead of rendering the index page where they've got links and stuff to go to and sign up. Also why is the code below not working.
class UsersController < ApplicationController
def new
#user = User.new
end
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
end
Your code isn't doing what you expect because the if statements are actually nested (you want elsif with this same structure -- or see my suggested fix below). Here's what your code, when properly formatted, actually looks like:
def create
if current_user.nil?
redirect_to dplace_index_path
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
end
end
Logically, you will never get down into the second if statement, because current_user must be nil to enter the first. Try something like this instead:
def create
if current_user
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
else
redirect_to dplace_index_path
end
end
I rearranged the code, but it should logically do what you want now. I put the "happy path" first (the current_user exists), and moved the redirect into the else statement.
General user authentication:
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to dashboard_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
Try:
def create
if current_user.blank? # .blank? will check both blank and nil
# logic when user is not logged in
redirect_to index_path
else
# logic when user is logged in
redirect_to dashboard_path
end
end
def create
redirect_to dplace_index_path unless current_user
# no need to check current_user again
#user = User.new(params[:user])
if #user.save
auto_login(#user)
redirect_to dplace_index_path
end
end
I want to use acts_as_commentable for two models (blog and post). I generated the comment model and added all my fields.
I created a comments_controller and in the create action I have to find blogs and posts, so for that to work I am doing something like this :-
def create
if controller_name == "blogs"
#blog = Blog.find(params[:comment][:blog_id])
#blog_comment = #blog.comments.new(:comment => params[:comment][:comment], :user_id => current_user.id)
if #blog_comment.save
flash[:success] = "Thanks for commenting"
redirect_to :back or root_path
else
flash[:error] = "Comment can't be blank!"
redirect_to :back or root_path
end
end
if controller_name == "topics"
#post = Post.find(params[:comment][:post_id])
#post_comment = #post.comments.new(:comment => params[:comment][:comment], :user_id => current_user.id)
if #post_comment.save
flash[:success] = "Thanks for commenting"
redirect_to :back or root_path
else
flash[:error] = "Comment can't be blank!"
redirect_to :back or root_path
end
end
I know it is pretty ugly but I don't know how to go ahead with this one, can anyone help me out?
I encountered the similar problem on one of my apps.
Here is what I've done:
class CommentsController < ApplicationController
before_filter :get_commentable
def create
#comment = #commentable.comments.build(params[:comment])
if #comment.save
...
else
...
end
end
private
def get_commentable
params.each do |k, v|
return #commentable = $1.classify.constantize.find(v) if k =~ /(.+)_id$/
end
end
end