Im trying to pass a client_id parameter from one of my views to a different models controller, but it seems like the param isn't being passed since I get the error "undefined method `client_id=' for nil:NilClass" in the set_client method. What am I doing wrong? ANy help would be appreciated. Thanks
<%= link_to 'New assessment', new_assessment_path(:client_id => #client.id), class: "btn btn-xs btn-success" %>
This is my controller:
class AssessmentsController < ApplicationController
before_action :set_assessment, only: [:show, :edit, :update, :destroy]
before_action :set_client, only: [:new]
def new
#assessment = Assessment.new
end
def create
#assessment = Assessment.new(assessment_params)
respond_to do |format|
if #assessment.save
format.html { redirect_to #assessment, notice: 'Assessment was successfully created.' }
format.json { render :show, status: :created, location: #assessment }
else
format.html { render :new }
format.json { render json: #assessment.errors, status: :unprocessable_entity }
end
end
end
def set_client
#assessment.client_id = params[:client_id]
end
Routes:
Rails.application.routes.draw do
resources :trainers
resources :clients
resources :assessments
root 'pages#home'
Main Reason for the undefined error is You are passing client_id to new method but not to the create method.
And What i understood from ur question is You want add a assessment to a client.
If this is your goal follow these steps
1.create association in respective models.
add the following line in Client.rb
has_many: :assesments
and add in Assement.rb
belongs_to: Client
2.Now change ur routes.rb.
resources clients do
resources assements do
end
end
3.Now check ur routes by executing this cmd rake routes
now your routes should be like this
/clients/:client_id/assements/new(.:format)
4.Now you dont need to pass the client id param manually.
Hope this will help you in solving ur problem.
cmt here if any..
Your error reads:
undefined method `client_id=' for nil:NilClass
That's coming from:
def set_client
#assessment.client_id = params[:client_id]
end
Which is being called before your new action due to:
before_action :set_client, only: [:new]
At that point, #assessment is nil in set_client because you haven't yet assigned the variable. Thus the error.
It has nothing to do with params not passing.
My suggestion is, remove the before_action and change the new action to:
def new
#assessment = Assessment.new(client_id: params[:client_id])
end
Do Assessment.find_by(client_id: params[:client_id]) in your set_client method.
You are trying to set the client_id in #assessment, and that variable is not defined when you are trying to set it.
before_action's callback is executed, as the name says, before the action (AKA method).
You should remove the before_action and add the setter within your new method
def new
#assessment = Assessment.new
#assessment.client_id = params[:client_id]
end
1.Set client in before_action
2.no need to create #assesment in new method
Change as below
class AssessmentsController < ApplicationController
before_action :set_assessment, only: [:show, :edit, :update, :destroy]
before_action :set_client, only: [:new]
def new
end
def create
#assessment = Assessment.new(assessment_params)
respond_to do |format|
if #assessment.save
format.html { redirect_to #assessment, notice: 'Assessment was successfully created.' }
format.json { render :show, status: :created, location: #assessment }
else
format.html { render :new }
format.json { render json: #assessment.errors, status: :unprocessable_entity }
end
end
end
def set_client
#client_id = Client.find_by(params[:client_id])
end
end
Related
I'm trying to create an API, but I get the error
"type": "NameError",
"message": "uninitialized constant Api::V1::ReservationOptionsController::ReservationOptions",
I cannot seem to find the issue here.
Code
routes
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :reservation_options, only: [:show, :create]
end
end
controllers/api/v1/reservation_options_controller.rb
class Api::V1::ReservationOptionsController < Api::V1::BaseController
acts_as_token_authentication_handler_for User, only: [:create]
def show
#reservation_option = ReservationOption.find(params[:id])
#reservation = #reservation_option.reservation
authorize #reservation_option
end
def create
#user = current_user
#reservation_option = ReservationOptions.new(reservation_option_params)
authorize #reservation_option
if #reservation_option.save
render :show, status: :created
else
render_error
end
end
private
def reservation_option_params
params.require(:reservation_option).permit(:option_id, :option_quantity, :reservation_id)
end
end
You have an error in the action create
def create
#user = current_user
# change this line
# #reservation_option = ReservationOptions.new(reservation_option_params)
#reservation_option = ReservationOption.new(reservation_option_params)
authorize #reservation_option
if #reservation_option.save
render :show, status: :created
else
render_error
end
end
It looks like ReservationOptions hasn't been defined anywhere, and you're using it in controllers/api/v1/reservation_options_controller.rb.
Make sure you've spelled it right, or that you have the appropriate model in app/models/reservation_option.rb. My guess is that it should be ReservationOption, since Rails model class names are typically singular.
I have a model named Group which has_many Posts and each Post has_many Comments. I can navigate to a group, create a post and then create a comment under that post. My issue is when I try and delete a comment I receive the below error about the redirect (the comment is deleted the redirect just doesn't happen).
undefined method `id' for nil:NilClass
this is the line in my destry action it does not like, which is weird because my update action has the same redirect and that works fine.
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully destroyed.' }
I tried adding [:destroy] onto the set_post before_action thinking that it might need that but no luck.
here's some of my routes
group_posts GET /groups/:group_id/posts(.:format) posts#index
POST /groups/:group_id/posts(.:format) posts#create
new_group_post GET /groups/:group_id/posts/new(.:format) posts#new
edit_group_post GET /groups/:group_id/posts/:id/edit(.:format) posts#edit
group_post GET /groups/:group_id/posts/:id(.:format) posts#show
PATCH /groups/:group_id/posts/:id(.:format) posts#update
PUT /groups/:group_id/posts/:id(.:format) posts#update
DELETE /groups/:group_id/posts/:id(.:format) posts#destroy
groups GET /groups(.:format) groups#index
POST /groups(.:format) groups#create
here's my comments_controller.rb
class CommentsController < ApplicationController
before_action :set_group, only: [:index, :show, :new, :edit, :create, :update]
before_action :set_post, only: [:index, :show, :new, :edit, :create, :update]
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /posts/:post_id/comments
def index
#comments = #post.comments.order(created_at: :desc)
end
def show
end
# GET /posts/:post_id/comments/new
def new
#comment = #post.comments.new
end
# # GET /posts/:post_id/comments/edit
# def edit
# end
# POST /posts/:post_id/comments
def create
# inserts current_user into the comments foriegn key for user_id.
#comment = #post.comments.new(comment_params.merge(user_id: current_user.id))
respond_to do |format|
if #comment.save
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/:post_id/comments/:id
def update
respond_to do |format|
if #post.comments.update(comment_params)
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully updated.' }
format.json { render :show, status: :ok, location: #comment }
else
format.html { render :edit }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/:post_id/comments/:id
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to group_post_url(group_id: #group.id, id: #post), notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
###################
# private methods
###################
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
def set_post
#post = Post.find(params[:post_id])
end
def set_group
#group = Group.find(params[:group_id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:content, :post_id, :user_id)
end
end
If you'd like to reference the #group instance variable, you should add :destroy to the before_action set_group callback:
before_action :set_group, only: [:index, :show, :new, :edit, :create, :update, :destroy]
You should also add :destroy to the before_action set_post callback as well
I'm hoping someone can help. I am using the Devise gem for registering and signing in users. I have a Profile controller. When an existing user logs in, I want them to be diverted to the Profile's show.html.erb page in order to view their profile. I would expect this would be done under the Sessions controller but it doesn't seem to do anything
The Sessions controller code is:
class Registrations::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
protected
def after_sign_in_path_for(resource)
profile_path(resource)
end
However, when a user registers, the redirect works successfully under the Registrations controller below:
class RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
protected
def after_sign_up_path_for(resource)
new_profile_path(resource)
end.
I also want to have a link to the users Profile page when they are logged in but when I do it throws up the following error
application.html.erb code for the link is below (I have tried a number of different variables in place of the '#profile' but with no success)
<li><%= link_to 'Show Profile', profile_path(#profile), :class => 'navbar-link' %></li>
The error I receive is:
ActionController::UrlGenerationError in Profiles#index
No route matches {:action=>"show", :controller=>"profiles", :id=>nil} missing required keys: [:id]
My routes (which I'm not sure are setup correctly:
Rails.application.routes.draw do
resources :profiles
get 'profiles/:id', to: 'profiles#show'
get '/profiles/new' => 'profiles#new'
get '/profiles/edit' => 'profiles#edit'
get '/profiles/index' => 'profiles#index'
root to: 'pages#index'
devise_for :users, :controllers => { :registrations => "registrations" }
Lastly, my Profile controller:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
def index
#search = Profile.search(params[:q])
#profiles = #search.result(distinct: true)
end
def show
#profile = Profile.find(params[:id])
end
def new
#profile = Profile.new
end
def create
#profile = Profile.new(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to #profile, notice: 'Your Profile was successfully created' }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new }
format.json { render json: #profile.errors, status: :unprocessable_entry }
end
end
end
def edit
#profile = Profile.find(params[:id])
end
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profile_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
def set_profile
#profile = Profile.find(params[:id])
end
private
def profile_params
params[:profile][:user_id] = current_user.id
params.require(:profile).permit(:full_name, :contact_number, :location, :makeup_type, :bio, :user_id, :image)
end
end
Any help is most appreciated.
Ok so there are two problems:
Redirecting after sign in
Url generation error in the application layout
Redirecting after sign in
You need to add the controller to your routes definition (like you have registrations.
devise_for :users, controllers: { registrations: "registrations", sessions: 'registrations/sessions' }
Url generation error in the application layout
I assume that the profile model is associated with the user (e.g. profile belongs_to user, or maybe user has_one profile). I also assume that you want to have a link for the current user's profile.
If that is the case then you could most likely do something like this:
<%= if current_user %>
<li>
<%= link_to 'Show Profile', profile_path(current_user.profile), :class => 'navbar-link' %>
</li>
<% end %>
Otherwise, you should set #profile in some before_action in the application controller or in any controller that uses the application layout.
In your application controller you want something like this
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def after_sign_in_path_for(user)
profile_path(current_user)
end
#user is the model name for example that you created with devise
end
I searched about this question, but had no success.
I´m trying to learn ruby on rails, came from php. I generated a webapp with the generation tool, second I generated a News controller with scaffold. The devise and pundit are installed too with gems.
The program works perfectly, the problem is related to the News module, I generated it with scaffold.
The routes where created with the command: resources :news
My idea is to create one _form.html.erb and it be called to create a new record or to updated an existing record. Some tutorials teach to create a new.html.erb and an update.html.erb file and duplicate the code, but I know that is possible to have partials as the main form part.
I´m using simple_form_for and the code to do the new is:
# GET /news/new
def new
#news = New.new
authorize New
end
The _form.html.erb
<%= simple_form_for(#news) do |f| %>
<%= f.input :titulo %>
<%= f.input :resumo %>
<%= f.button :submit %>
<% end %>
When I enter to edit, it works, but to add a new it throws.
ActionController::UrlGenerationError at /news/new
No route matches {:action=>"show", :controller=>"news", :locale=>:en} missing required keys: [:id]
Sorry for my bad english, I´m without direction here, is there any way that I can solve it?
Thanks.
====== UPDATED =======
routes.rb
Rails.application.routes.draw do
root to: 'visitors#index'
devise_for :users
resources :users
resources :news
end
New.rb (Model)
class New < ActiveRecord::Base
belongs_to :user
end
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
before_filter :set_locale
def default_url_options(options={})
{ locale: I18n.locale }
end
private
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
end
news_controller.rb (Complete)
class NewsController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized
#before_action :set_news, only: [:show, :edit, :update, :destroy]
# GET /news
# GET /news.json
def index
#news = New.all
authorize New
end
# GET /news/1
# GET /news/1.json
def show
#news = New.find(params[:id])
authorize New
end
# GET /news/new
def new
#news = New.new
authorize New
end
# GET /news/1/edit
def edit
#news = New.find(params[:id])
authorize New
end
# POST /news
# POST /news.json
def create
#news = New.new(news_params)
respond_to do |format|
if #news.save
format.html { redirect_to #news, notice: 'New was successfully created.' }
format.json { render :show, status: :created, location: #news }
else
format.html { render :new }
format.json { render json: #news.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /news/1
# PATCH/PUT /news/1.json
def update
respond_to do |format|
if #news.update(news_params)
format.html { redirect_to #news, notice: 'New was successfully updated.' }
format.json { render :show, status: :ok, location: #news }
else
format.html { render :edit }
format.json { render json: #news.errors, status: :unprocessable_entity }
end
end
end
# DELETE /news/1
# DELETE /news/1.json
def destroy
#news.destroy
respond_to do |format|
format.html { redirect_to news_url, notice: 'New was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_news
#news = New.find(params[:id])
end
private
def news_params
params.require(:news).permit(:titulo, :resumo, :texto, :published_at, :user_id)
end
end
Command rake routes
news_index GET /news(.:format) news#index
POST /news(.:format) news#create
new_news GET /news/new(.:format) news#new
edit_news GET /news/:id/edit(.:format) news#edit
news GET /news/:id(.:format) news#show
PATCH /news/:id(.:format) news#update
PUT /news/:id(.:format) news#update
DELETE /news/:id(.:format) news#destroy
Thanks in advance.
======= UPDATE 2 ===========
Changing my New action to this:
def new
#news = New.create(params[:id])
end
It solved, but everytime I enter, it creates an empty record...
Use news_index_path for GET /news and POST /news. Rails doesn't figure out the pluralization correctly for the "news" term.
Check the output of rake routes, it will be obvious.
I get an error when I try to visit the below url in my rails app.
http://localhost:3000/origtexts/1/reviews/new
routes.rb
resources :origtexts do
resources :reviews
end
It passes the param of the review (1) correctly but I the error I get is undefined method `review' for the line in ReviewsController#new.
reviews_controller.rb
class ReviewsController < ApplicationController
before_filter :find_origtext
before_filter :find_review, :only => [:show, :edit, :update, :destroy]
def new
#review = #origtext.review.build
end
def show
end
def create
#review = #origtext.reviews.build(params[:review])
if #review.save
flash[:notice] = 'Review has been created'
redirect_to [#origtext, #review]
else
flash[:alert] = 'Review has not been created'
render :action => 'new'
end
end
private
def find_origtext
#origtext = Origtext.find(params[:origtext_id])
end
def find_review
#review = #origtext.reviews.find(params[:id])
end
end
Any advice on how to fix this?
Change review to reviews in this line
#review = #origtext.review.build
To
#review = #origtext.reviews.build