I let users to upload photos using paperclip, but there is no ownership in the photo. Which means, I don't know who uploaded the photos at all.
Here, I would like when someone uploads a picture you know which user uploaded it. i have a user_id column. but i dont know how to implement the code in the pic controller
How do I do that? Thanks!
class PicsController < ApplicationController
before_action :find_pic, only: [:show, :edit, :update, :destroy]
def index
#user = User.find( params[:user_id])
#pics = Pic.all.order("created_at DESC")
end
def show
end
def new
#pic = Pic.new
end
def create
#pic.user = current_user
#pic = Pic.new(pic_params)
if #pic.save
redirect_to #pic, notice: "Yes it was posted"
else
render 'new'
end
end
def edit
#user = User.find(params[:user_id])
#profile = #user.profile
end
def update
if #pic.update(pic_params)
redirect_to #pic, notice: "Congrates Pic was upaded"
else
render 'new'
end
end
def destroy
#pic.destroy
redirect_to users_path
end
private
def pic_params
params.require(:pic).permit(:title, :description, :profile_id)
end
def find_pic
#pic = Pic.find(params[:id])
end
end
class UsersController < ApplicationController
before_action :authenticate_user!
def index
#pics = Pic.all.order("created_at DESC")
end
def show
#user = User.find(params[:id])
#pics = User.find_by(user_name: params[:user_name])
end
end
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :only_current_user
def new
#user = User.find( params[:user_id])
#profile = Profile.new
end
def create
#user = User.find(params[:user_id])
#profile = #user.build_profile(profile_params)
if #profile.save
redirect_to user_path( params[:user_id])
else
render action: :new
end
end
def edit
#user = User.find(params[:user_id])
#profile = #user.profile
end
def update
#user = User.find(params[:user_id])
#profile = #user.profile
if #profile.update_attributes(profile_params)
flash[:success] = "Profile Updated"
redirect_to user_path(params[:user_id])
else
render action: :edit
end
end
private
def profile_params
params.require(:profile).permit(:avatar, :user_name, :contact_email, :description)
end
def only_current_user
#user = User.find(params[:user_id])
redirect_to(root_url) unless #user == current_user
end
end
If the user can be identified during the upload process, you can try to pass the user_id in a hidden_field during upload. You said you already created the user_id column.
<%= f.hidden_field :user_id , value: #user.id %>
for this code to work you need to find the #user in your controller action. Similar to what you are doing already in your 'index' action: find user by the :user_id
If you are using devise for User you can use current_user.id instead.
Related
I have this code, it works perfectly for me, the problem is that it does not save me in the database the first time, I must reload the page and then try again to make it work.
I can't find the error
then I am going to leave you the code of my controller so that you can give me a hand of what may be happening
class EvolutionsController < ApplicationController
before_action :load_patient
before_action :set_evolution, only: :show
before_action :verify_permission, only: %i[new show create edit update destroy]
def index
#evolutions = #patient.evolutions # You could skip this and just use #patient.evolutions in your view if you like
end
def show
end
def new
#evolution = #patient.evolutions.build
end
def create
#evolution = #patient.evolutions.build(evolution_params)
if #evolution.save
redirect_to patients_url, notice: 'La evolucion fue agregada con exito'
else
render :new
end
end
def edit
end
def destroy
#evolution = #patient.evolutions.find(params[:id])
#evolution.destroy
redirect_to patient_path(#patient)
flash[:notice] = "EvoluciĆ³n eliminada"
end
private
def load_patient
#patient = Patient.find(params[:patient_id])
end
def set_evolution
#evolution = #patient.evolutions.find(params[:id])
end
def verify_permission
redirect_to patients_path if !user_signed_in? || #patient.user != current_user
end
def evolution_params
params.require(:evolution).permit(:motivo, :entrevista, :patient_id)
end
end
I keep getting the error destroy action can not be found in the messagesController. But i have the destroy action setup i don't get why i am getting this message error. Can some one tell me why i can getting this error?
class MessagesController < ApplicationController
before_action :find_message, only: [:show, :edit, :update, :destroy]
def index
#messages = Message.all.order("created_at DESC")
end
def show
end
def new
#message = Message.new
end
def create
#message = Message.new(message_params)
if #message.save
redirect_to root_path
else
render 'new'
end
def edit
end
def update
if #message.update(message_params)
redirect_to message_path
else
render 'edit'
end
end
def destroy
#message.destroy
redirect_to root_path
end
end
private
def message_params
params.require(:message).permit(:title, :description)
end
def find_message
#message = Message.find(params[:id])
end
end
You missed an end closure for your create action. The right way should be this:
def create
#message = Message.new(message_params)
if #message.save
redirect_to root_path
else
render 'new'
end
end
def edit
end
Your create action is missing an end statement:
def create
#message = Message.new(message_params)
if #message.save
redirect_to root_path
else
render 'new'
end
# This is defined before create is closed
def edit
end
Hello I am learning rails and I have made a mistake that error message shows when I submit the article but can't seem to know where the problem is. I think it's a controller?
Github files of my code:
GitHub Project
users_controller.rb
class UsersController < ApplicationController
def index
#users = User.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "welcome to the alpha blog #{#user.username}"
redirect_to articles_path
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
flash[:success] = "Your account was updated successfully"
redirect_to articles_path
else
render 'edit'
end
end
def show
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:username, :email, :password)
end
end
articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: [:edit, :update, :show, :destroy]
# Helppppp!
def index
#articles = Article.all
end
def new
#article = Article.new
end
def edit
#article = Article.find(params[:id])
end
def create
#article = Article.new(article_params)
#article.user = User.new
if #article.save
flash[:success] = "Article was successfully created"
redirect_to article_path(#article)
else
render :new
end
end
def update
if #article.update(article_params)
flash[:success] = "Article was successfully updated."
redirect_to article_path(#article)
else
render 'edit'
end
end
def show
end
def destroy
#article.destroy
flash[:danger] = "Article was successfully deleted"
redirect_to articles_path
end
private
def set_article
#article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :description)
end
end
Look at your method:
def create
#article = Article.new(article_params)
#article.user = User.new
...
end
You are trying to assign empty user to your article object. You should pass user_id as a param (don't forget to add it as a permitted param in article_params) and your code should be:
#article.user = User.find(article_params[:user_id])
Fixed it by defining current_user method in the application_controller.rb and added the following:
**application_controller.rb**
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_user, :logged_in?
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def logged_in?
!!current_user
end
def require_user
if !logged_in?
flash[:danger] = "You must be logged in to perform that action"
redirect_to root_path
end
end
end
articles_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: [:edit, :update, :show, :destroy]
before_action :require_user, except: [:index, :show]
before_action :require_same_user, only: [:edit, :update, :destroy]
def index
#articles = Article.paginate(page: params[:page], per_page: 5)
end
def new
#article = Article.new
end
def edit
end
def create
#article = Article.new(article_params)
#article.user = current_user #code that needs fix
if #article.save
flash[:success] = "Article was successfully created"
redirect_to article_path(#article)
else
render :new
end
end
def update
if #article.update(article_params)
flash[:success] = "Article was successfully updated."
redirect_to article_path(#article)
else
render 'edit'
end
end
def show
end
def destroy
#article.destroy
flash[:danger] = "Article was successfully deleted"
redirect_to articles_path
end
private
def set_article
#article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :description)
end
def require_same_user
if current_user != #article.user
flash[:danger] = "You can only edit or delete your own article"
redirect_to root_path
end
end
end
I am having a bit of trouble displaying the most recent created comments based from the time/date that they were created in my views/post/show.htmlerb file. I just got my posts_controller to display the most recent created posts from the def index action but now in my def show action the following code doesn't work:
#comment_date_order = Comment.find(params[:id]).comments.order('created_at DESC')
this is my full posts_controller.rb file:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :vote]
before_action :require_user, only: [:new, :create, :edit, :update, :vote]
before_action :require_creator, only:[:edit, :update]
def index
#posts = Post.page(params[:page]).order('created_at DESC').per_page(10)
end
def show
#comment = Comment.new
#comment_date_order = Post.find(params[:id]).comments.order('created_at DESC')
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.creator = current_user
if #post.save
flash[:notice] = "You created a post!"
redirect_to posts_path
else
render :new
end
end
def edit
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
flash[:notice] = "You updated the post!"
redirect_to post_path(#post)
else
render :edit
end
end
def vote
Vote.create(voteable: #post, creator: current_user, vote: params[:vote])
respond_to do |format|
format.js { render :vote } # Renders views/posts/vote.js.erb
end
end
private
def post_params
params.require(:post).permit(:url, :title, :description)
end
def set_post
#post = Post.find(params[:id])
end
def require_creator
access_denied if #post.creator != current_user
end
end
comments_controller.erb file:
class CommentsController < ApplicationController
before_action :require_user
def create
#post = Post.find(params[:post_id])
#comment = Comment.new(params.require(:comment).permit(:body))
#comment.post = #post
#comment.creator = current_user
if #comment.save
flash[:notice] = "Your comment was created!"
redirect_to post_path(#post)
else
render 'posts/show'
end
end
def edit
#comment = Comment.find(params[:id])
#post = Post.find(params[:post_id])
end
def update
#comment = Comment.find(params[:id])
if #comment.update(comment_params)
flash[:notice] = "You updated your comment!"
redirect_to post_path(#post)
else
render :edit
end
end
private
def comment_params
params.require(:comment).permit(:body)
end
def set_comment
#comment = Comment.find(params[:id])
end
end
First you would need a relation between Post and Comment if you dont already.
I would just create a def in the Post model.
class Post < ActiveRecord::Base
has_many :comments
def newest_comments
self.comments.order('created_at DESC')
end
end
That way you could also make a oldest_post method and uses it directly in the view
<%= #post.newest_post.each do |comment| %>
Also as best practice. Try and not to create too many instance vars in your controller. Remember fat models, skinny controllers.
To create an user in the example bellow I have to load #projects and #companies as they are mandatory for creating user.
class UsersController < ApplicationController
def new
#user = User.new
# duplication here
#projects = Project.all
#companies = Company.all
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user
else
# and here
#projects = Project.all
#companies = Company.all
render :action => "new"
end
end
end
I have to load these dependencies in both (duplication) cases, for the new and create action when the user is invalid.
I can refactor by encapsulating these dependencies in a method load_user_dependencies.
class UsersController < ApplicationController
def new
#user = User.new
load_user_dependencies
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user
else
load_user_dependencies
render :action => "new"
end
end
private
def load_user_dependencies
#projects = Project.all
#companies = Company.all
end
end
Or by adding them as a helper_methods.
class UsersController < ApplicationController
helper_method :projects, :companies
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user
else
render :action => "new"
end
end
def projects
#projects ||= Project.all
end
def companies
#companies ||= Company.all
end
end
I can also create a View Object
class UserView
def products
#products ||= Product.all
end
def companies
#companies ||= Company.all
end
end
class UsersController < ApplicationController
def new
#user = User.new
#user_view = UserView.new
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user
else
#user_view = UserView.new
render :action => "new"
end
end
end
Other option is to use a Presenter
class UserPresenter < SimpleDelegator
def products
#products ||= Product.all
end
def companies
#companies ||= Company.all
end
end
class UsersController < ApplicationController
def new
#user = UserPresenter.new User.new
end
def create
#user = UserPresenter.new User.new(params[:user])
if #user.save
redirect_to #user
else
render :action => "new"
end
end
end
How do you guys usually deal with scenario?
It's a bit of a personal taste issue, but in our projects if it's suitable we do it in the view, and if it's complex we do it in a before_filter.
View - suitable if it's something that doesn't have any logic, no need to create a variable for this. Super useful if your form is contained in a partial as it's only done once so easily maintained.
<%= form.select :project_id, Project.all, :id, :name %>
If it's something that can change depending on any factors then a before_filter in controller:
MyController
before_filter :find_projects, :except => [:destroy, :some_method] # Will load the values but not for the destroy or some_method actions
def find_projects
#projects = Project.where(:some conditions => true)
end