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
Related
Hello beautiful community. I am a newbie in Rails and I have a project where I have to register patients and each patient has evolutions. I have been able to register and save the patients in the database, but I cannot save the records of the evolution of these patients.
I am going to show my code for whoever can and wants to guide me. I would appreciate very much
#BACK OFFICE ROUTES-PACIENTES
resources :patients do
resources :evolutions
end
CONTROLLERS:
class PatientsController < ApplicationController
def create
#patient = current_user.patients.new patient_params
if #patient.save
return redirect_to patients_url, notice: 'El paciente fue agregado con exito'
end
render :new
end
class EvolutionsController < ApplicationController
before_action :authenticate_user!
def index
#evolutions = #patient.Evolution.all
end
def new
#evolution = Evolution.new
end
def edit
end
def create
#evolution = current_user.evolutions.new evolution_params
if #evolution.save
return redirect_to patients_url, notice: 'La evolucion fue agregada con exito'
end
render :new
end
def show
#evolution = Evolution.find params[:id]
end
private
def evolution_params
params.require(:evolution).permit(:motivo, :evolution, :patient_id)
end
end
As I was saying, the patients have no problems, but the evolutions I cannot save in the database.
I expect your ApplicationController already has a before_action :authenticate_user!, otherwise current_user wouldn't be working in your PatientsController. So, you can remove that.
In your Evolutions#index action you refer to the instance variable #patient despite this not having been set anywhere. Based on your routes this is a nested resource under Patient, and so your index action should look something like this:
def index
#patient = Patient.find(params[:patient_id]
#evolutions = #patient.evolutions # You could skip this and just use #patient.evolutions in your view if you like
end
Likewise, your new action should be modified to generate a new evolution for a specific patient:
def new
#patient = Patient.find(params[:patient_id]
#evolution = #patient.evolutions.build
end
This will create a new, unsaved instance of Evolution which already belongs to the appropriate user.
Finally, we need to update the create action to handle the nested resource also:
def create
#patient = Patient.find(params[:patient_id]
#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
As you can see, we now have repeated code in our actions for finding the Patient from the params ... we can DRY this up by moving it to a before action.
Pulling this all together:
class EvolutionsController < ApplicationController
before_action :load_patient
def index
#evolutions = #patient.evolutions # You could skip this and just use #patient.evolutions in your view if you like
end
def show
#evolution = #patient.evolutions.find(params[:id])
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
private
def load_patient
#patient = Patient.find(params[:patient_id]
end
def evolution_params
params.require(:evolution).permit(:motivo, :evolution, :patient_id)
end
end
I'm having a association between user, store and item like this:
user has one store
store has many items
item belongs to store
So when I create item it must belongs to the current user's store
Now, I logged in as user_1 , I want to search for user_2's item. But if I didn't create user_1's store, It keep redirecting me to localhost:3000/stores
in items_controller.rb:
class ItemsController < ApplicationController
before_action :find_item, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, only: [:new, :edit]
def index
if params[:category].blank?
#items = Item.all.order("created_at DESC")
end
if params[:category]
#category_id = Category.find_by(name: params[:category]).id
#items = Item.where(category_id: #category_id).order("created_at DESC")
end
end
def show
end
def new
#store = current_user.store
#item = #store.items.build
#categories = Category.all.map{ |c| [c.name, c.id] }
end
def update
#item.category_id = params[:category_id]
if #item.update(item_params)
redirect_to item_path(#item)
else
render 'edit'
end
end
def create
#store = current_user.store
#item = #store.items.build(item_params)
#item.category_id = params[:category_id]
if #item.save
flash[:success] = "Creating item success"
redirect_to #item
else
render 'new'
end
end
private
def item_params
params.require(:item).permit(:code, :name, :description, :producer, :item_img, :store_id,
:category_id )
end
def find_item
#item = Item.find(params[:id])
end
def find_user
#user = User.find_by(params[:user_id])
end
end
in stores_controller.rb:
class StoresController < ApplicationController
before_action :find_store, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :find_user
def show
if current_user.store.blank?
redirect_to new
else
#items = Item.where(store_id: #store.id)
end
end
def index
#stores = Store.all.order("created at DESC")
end
def new
#store = current_user.build_store
end
def create
#store = current_user.build_store(store_params)
if #store.save
session[:store_id] = #store.id
flash[:success] = "Creating item success"
redirect_to #store, notice: 'success'
else
render 'new'
end
end
private
def store_params
params.require(:store).permit( :name , :user_id)
end
def find_store
#store = Store.find(params[:id])
end
def find_user
#user = Store.find_by(params[:user_id])
end
end
The error raised whenever I click on the button in items/show.html.erb.
In items/show.html.erb:
<button>see more item from:<%= link_to #item.store.name, store_path(#item.store.id)%></button>
in routes.rb:
devise_for :users
resources :items
resources :stores
In the show method for stores_controller, I still want to load the current_user's store in navbar section to make sure he can add more items to his store when he logged in.
I'm still a newbie in rails and I'm looking for solutions to solve this problem :-)
If a store requires a user_id then you don't need before_action :find_user because you can get the store's user just by calling store.user
It looks like you require the current_user to have a store but what if they are not logged in? Shouldn't it be this?
def show
if current_user && current_user.store.blank?
redirect_to new
else
#items = Item.where(store_id: #store.id)
end
end
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.
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
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.