Using index with Presenter causes NoMethodError - ruby-on-rails

I tried to learn about presenter and did the following classes
User model with id, first_name, last_name, email
user_controller with the following methods
def index
#users = User.all
render_user_json #users
end
def show
#user = User.find_by_id(params[:id])
if #user.nil?
render json: { message: 'User can not be found' }, status: 404
return
end
render_user_json #user
end
def render_user_json(user)
render json: ::Presenters::User::UserPresenter.new(user).generate
end
UserPresenter class
module Presenters
module User
class UserPresenter
attr_reader :user
def initialize(user)
#user = user
end
def generate
{
id: #user.id,
first_name: #user.first_name,
last_name: #user.last_name,
email: #user.email
}
end
end
end
end
When I go to localhost:3000/users/id it works well
but when I go to localhost:3000/users I get the following error
NoMethodError (undefined method `id' for #<User::ActiveRecord_Relation:0x00007f9952ac4930>
Did you mean? ids):
lib/presenters/user/user_presenter.rb:14:in `generate'
app/controllers/users_controller.rb:49:in `render_user_json'
app/controllers/users_controller.rb:9:in `index'
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_source.erb (4.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (108.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_markup.html.erb (0.4ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.4ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/console.js.erb within layouts/javascript (91.6ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/main.js.erb within layouts/javascript (0.7ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.8ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/index.html.erb (210.6ms)
It seems like it doesn't passed as single users

Rather than this:
render_user_json #users
Either make another method render_users_json (note the plural users) or just call the render from the index method directly like this:
# inside index method
render json: users.map do |user|
::Presenters::User::UserPresenter.new(user).generate
end

Related

Devise sets current_user to nil after I change this users password and sign them back in

Here is the code I'm trying to use in my controller:
profiles_controller.rb:
class ProfilesController < ApplicationController
...
def update
respond_to do |format|
# assume valid data sent (I've already tested for this)
if #user.update(user_params)
# password_reset? check's parameter passed to action that a check box was
# checked (which enables/disables password/confirmation fields. If unchecked,
# fields are disabled and no password parameters are sent to this action.
# #user was set to current_user in a before_action already
# inspecting #user at this point returns the same thing as current_user here
sign_in(:user, #user) if password_reset?
# current_user is still set to #user and is valid
# after redirection current_user becomes nil
format.html {
redirect_to home_path, notice: 'Your profile was successfully updated.'
}
else
format.html { render :edit }
end
end
end
...
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
#user_params ||= params.require(:user).permit(:first_name, :last_name, :email, :phone, :password, :password_confirmation, :reset_password)
end
def password_reset?
#user_params["reset_password"] == "1"
end
end
application_controller.rb:
class ApplicationController < ActionController::Base
...
private
...
def require_user
logger.debug "IN REQUIRE_USER, CURRENT_USER IS: #{current_user.inspect}"
unless current_user
store_location
redirect_to new_user_session_url, notice: "That url doesn't exist."
return false
end
end
def require_admin
# this line will actually log a user in
#sign_in(:user, User.first) unless current_user
logger.debug "IN REQUIRE_ADMIN, CURRENT_USER IS: #{current_user.inspect}"
unless current_user && current_user.is_admin?
redirect_to(home_path, notice: "That url doesn't exist.") and return false
end
end
...
end
development.log:
Started PATCH "/profile" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by ProfilesController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"....", "user"=>{....}, "commit"=>"Update Profile"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:47
IN REQUIRE_USER, CURRENT_USER IS: #<User id: 1 ....>
(0.1ms) begin transaction
↳ app/controllers/profiles_controller.rb:16
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."id" != ? LIMIT ? [["email", "...."], ["id", 1], ["LIMIT", 1]]
↳ app/controllers/profiles_controller.rb:16
User Update (0.3ms) UPDATE "users" SET "encrypted_password" = ?, "updated_at" = ? WHERE "users"."id" = ? [["encrypted_password", "$2a$11...."], ["updated_at", "2019-05-28 17:38:45.346414"], ["id", 1]]
↳ app/controllers/profiles_controller.rb:16
(2.3ms) commit transaction
↳ app/controllers/profiles_controller.rb:16
PASSWORDS PASSED IN SO USER PASSWORD CHANGE OCCURRED
REDIRECTING TO HOME PATH
Redirected to http://localhost:3000/admin
Completed 302 Found in 121ms (ActiveRecord: 3.2ms)
Started GET "/admin" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by Admin::PagesController#index as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:65
IN REQUIRE_ADMIN, CURRENT_USER IS: nil
Redirected to http://localhost:3000/
Filter chain halted as :require_admin rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Started GET "/" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by PagesController#index as HTML
Rendering pages/index.html.erb within layouts/application
Rendered pages/index.html.erb within layouts/application (0.7ms)
Rendered application/_navigation.html.erb (1.7ms)
Rendered application/_alert.html.erb (0.3ms)
Completed 200 OK in 1152ms (Views: 1151.2ms | ActiveRecord: 0.0ms)
I've searched around and seen by_pass: true being passed to sign_in but that doesn't help. I've also tried #current_user = #user once I've signed the user in (#current_user is the direct instance variable for the Devise controller btw) and that does not help either.
Any ideas?
Devise ignores signin if the user is already signed in, try:
if #user.saved_change_to_encrypted_password? # for rails 5+, for previous - .encrypted_password_changed?
sign_in #user, force: true
end
You can signin new session if the user is already signed in.
Devise said
# Sign in a user bypassing the warden callbacks and stores the user
# straight in session. This option is useful in cases the user is
# signed in, but we want to refresh the credentials in session.
Please use like below one.
bypass_sign_in(#user)

Why isn't my form saving but working with the API only?

I have my form to save to my Stripe_account table. I recently nested the resources and now the form won't save to my database tables. I have it still working with the Stripe API and working there though.
What in my code is lacking?
User Model:
has_one :stripe_account
Stripe_account Model:
belongs_to :users
Stripe_account controller:
def new
#stripe_account = StripeAccount.new
#user = User.find(params[:user_id])
end
def create
#stripe_account = StripeAccount.new(stripe_account_params)
#user = User.find(params[:user_id])
acct = Stripe::Account.create({
.....
.....
#stripe_account.id = current_user.id
#stripe_account.acct_id = acct.id
respond_to do |format|
# #user = User.find(params[:id])
if #stripe_account.save
# current_user = #user
#user.stripe_account = acct.id
format.html { redirect_to new_bank_account_path, notice: 'Stripe account was successfully created.' }
format.json { render :show, status: :created, location: #stripe_account }
else
format.html { render :new }
format.json { render json: #stripe_account.errors, status: :unprocessable_entity }
end
end
end
View:
<%= form_for ([#user, #stripe_account]) do | f | %>
Routes:
resources :users do
resources :stripe_accounts
end
#added for testing
get 'stripe_' => "stripe_account#create"
get 'stripe_new' => "stripe_account#new"
Here's my routes maybe can help?: https://pastebin.com/RVWd2Qq9
Now even though I don't have the "bankaccount" controller or models set up correctly yet, shouldn't it be at least attempting to go there and saving the stripe_account? Just making sure that's not the issue. But it appears it's failing because a new form reloads.
The API is successfully going through as well and the accounts are appearing within stripe, just not my own database.
What in my programming is wrong?
Update to add cmd response:
Started POST "/users/2/stripe_accounts" for 127.0.0.1 at 2018-11-10 00:11:26 -0500
Processing by StripeAccountsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nz1234567890iJuFwsm/Z4ylhE6zoGdWN6QCfWtDZTH1sxZu/WCdWMKBGkc4zoZ2dOgk9c8UDwRzgqdxrT/sA==", "stripe_account"=>{"account_type"=>"individual", "business_name"=>"", "business_tax_id"=>"", "first_name"=>"Dill", "last_name"=>"Pickles", "ssn_last_4"=>"1234", "dob_month"=>"3", "dob_day"=>"4", "dob_year"=>"1917", "address_line1"=>"198 berry avenue", "address_city"=>"san fran", "address_state"=>"CA", "address_postal"=>"90213", "tos"=>"1", "id"=>"2"}, "full_account"=>"{:value=>\"true\"}", "button"=>"", "user_id"=>"2"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ app/controllers/stripe_accounts_controller.rb:49
(0.1ms) begin transaction
↳ app/controllers/stripe_accounts_controller.rb:91
(0.1ms) rollback transaction
↳ app/controllers/stripe_accounts_controller.rb:91
Rendering stripe_accounts/new.html.erb within layouts/application
Rendered stripe_accounts/_account_form.html.erb (9.4ms)
Rendered stripe_accounts/new.html.erb within layouts/application (12.5ms)
Rendered layouts/_navbar.html.erb (1.9ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 3202ms (Views: 190.0ms | ActiveRecord: 2.4ms)
Validation failed: User must exist
You can either use optional :true to resolve the error
#stipe_account.rb
belongs_to :user, optional: true
#^ should be singular
OR
Assign the user_id in the create action like so
#stripe_account.user_id = current_user.id #add this line
Update:
undefined method `user_id=' for StripeAccount:0x001234f4c58692ae8 Did
you mean? user="
The error is because you don't have user_id column in stripe_accounts table. Generate a migration that will do the job for you
rails g migration add_user_id_to_stripe_accounts user_id:integer
and do rails db:migrate

undefined method `nil' for #<Admin:0x00000011ead6f0>

I'm using rails_admin and I have overrided delete action with adding some line of code:
if request.get? # DELETE
respond_to do |format|
format.html { render #action.template_name }
format.js { render #action.template_name, layout: false }
end
elsif request.delete? # DESTROY
redirect_path = nil
# puts 'CUSTOM DELETE'
# This code to assign current user that will delete following object.
# History tracker can not assign current_user by itself.
if #object.has_attribute?(:updater_id)
#object.updater = _current_user
#object.save
end
#auditing_adapter && #auditing_adapter.delete_object(#object, #abstract_model, _current_user)
if #object.destroy
flash[:success] = t('admin.flash.successful', name: #model_config.label, action: t('admin.actions.delete.done'))
redirect_path = index_path
else
flash[:error] = t('admin.flash.error', name: #model_config.label, action: t('admin.actions.delete.done'))
redirect_path = back_or_index
end
redirect_to redirect_path
end
When the delete action is called it throws:
undefined method `nil' for #<Admin:0x00000011ead6f0>
Yes that is strange. I always get undefined methods for nilClasses but this. This is nil for defined object. This happens on #object.updater - _current_user line
#object is model that will be destroyed. _current_user is logged in Admin model.
Why this error is happening?
The models I use are: Category, SubCategory, Sub2Category and Admin.
Category has_many SubCategory, SubCategory has_many Sub2Category. Admin is updater and _current_user.
This error happened when I try to delete Sub2Category via rails_admin.
Backtrace:
NoMethodError (undefined method `nil' for #<Admin:0x00000013b9b960>):
config/initializers/rails_admin_delete_override.rb:40:in `block (2 levels) in <class:Delete>'
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (25.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (33.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (84.0ms)

undefined method `projects' for nil:NilClass

Is my project class is nill or what, can any one explain me this error.
NoMethodError (undefined method projects' for nil:NilClass):
app/controllers/project_controller.rb:8:inindex'
Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_source.erb
(6.2ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.0ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb
within rescues/layout (50.0ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb
(0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb
within layouts/inlined_string (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb
within layouts/inlined_string (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb
within layouts/inlined_string (0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (41.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb
within layouts/javascript (0.3ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.4ms) Rendered
/Users/ajaysithagari/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (93.4ms)
Here is my project controller
before_action :confirm_logged_in
before_action :find_company
def index
#projects = #company.projects.sorted
end
def show
#project = Project.find(params[:id])
end
def new
#project = Project.new()
end
def create
#project = Project.new(project_params)
if #project.save
redirect_to(:action => 'index')
else
render('new')
end
end
def edit
#project = Project.find(params[:id])
end
def update
#project = Project.find(params[:id])
if #project.update_attributes(project_params)
redirect_to(:action => 'index')
else
render('new')
end
end
def delete
#project = Project.find(params[:id])
end
def destory
#project = Project.find(params[:id])
#project.destroy
redirect_to(:action => 'index')
end
private
def project_params
params.require(:project).permit(:name, :position, :type_of_project, :description, :no_of_tasks)
end
def find_company
if params[:company_id]
#company = Company.find(params[:company_id])
end
end
end
So actually what iam doing here is before entering in to projects we need to find the company_id and in index #projects = #company.projects.sorted means that company has many projects.
The problem is with the if params in the def find_company. For the index function this is not set.
change def index to:
def index
#projects = Project.sorted
end
UPDATE: made an error I think:
def index
#projects = Project.all.sorted #or leave the call to sorted out completely
end

Error on rendering show action

I am trying to render show action by passing parameters, but the show page is not being rendered when there are no users signed in. This is my controller:
class QrCodesController < ApplicationController
def show
#user = User.find_by_qr(params[:id])
if #user.nil?
redirect_to root_path
end
end
end
and this is my view:
This is the qr-code page of <%= #user.fname %> <%= #user.lname%>
However, the show page is perfectly rendered when any user is signed in.
The rails server also shows perfectly rendered show action:
Started GET "/qr_codes/9M9JZLiemrNdS_g90mZ14w" for 127.0.0.1 at 2013-08-02 18:29:55 +0545
Processing by QrCodesController#show as HTML
Parameters: {"id"=>"9M9JZLiemrNdS_g90mZ14w"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."qr" = '9M9JZLiemrNdS_g90mZ14w' LIMIT 1
Rendered qr_codes/show.html.erb within layouts/application (0.7ms)
Rendered layouts/_shim.html.erb (0.0ms)
Web Load (0.3ms) SELECT "webs".* FROM "webs" WHERE "webs"."id" = 2 LIMIT 1
Rendered layouts/_header.html.erb (3.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 54ms (Views: 52.4ms | ActiveRecord: 0.5ms)
I am using rails 3.2.13, ruby 1.9.3p429 along with devise 3.0.0. The User model was not generated by devise.
Please Help.
EDIT:
This is the link that triggers the show action:
http://localhost:3000/qr_codes/9M9JZLiemrNdS_g90mZ14w
Since #user is equal to # when you print it, it is clearly not equal to nil and the redirection is not happening. You need to either change the code in find_by_qr to return nil if not found, or determine what other way that that method is using to represent not found, and change your conditional to use that.
Try this instead:
#user = User.find_by_qr(params[:id])
if #user
respond_to do |format|
format.html
end
else
redirect_to root_path
end

Resources