Actionview template error undefined method for nil nilclass

I do not manage to understand the following error that pops up when I run my tests ActionView::Template::Error: undefined method `name' for nil:NilClass # ./app/views/shared/_navbaruser.html....

I do not manage to understand the following error that pops up when I run my tests

 ActionView::Template::Error:
   undefined method `name' for nil:NilClass
 # ./app/views/shared/_navbaruser.html.erb:5:in `_app_views_shared__navbaruser_html_erb__1173572034888802020_70230060606960'
 # ./app/views/confirmations/indexuser.html.erb:9:in `_app_views_confirmations_indexuser_html_erb___3677980567853899736_70230060569840'
# ./spec/views/confirmations/indexuser.html.erb_spec.rb:5:in `block (2 levels) in <top (required)>'

My template indexuser calls a partial _navbaruser with the following line

<%= render "shared/navbaruser" %>

The partial has

<%= @current_user.name %>

Current_user is defined in my helper

def current_user
if (user_id = session[:user_id])
  @current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
  user = User.find_by(id: user_id)

   if user && user.authenticated?(:remember, cookies[:remember_token])
  log_in user
    @current_user = user
  end
  end
end

I get the error when I run my test. The application works fine and I do get the name of the current_user when someone is logged in. In the controller I tried:

1) To fully empty the controller (I do not put anything under the method that calls the template)

2) Just put one line to define current_user

@current_user = User.first

In both cases, I get the error when I run my test. Could anyone give me some hints on where to look for to correct this error? Could it be that defining current_user in a helper method triggers this template error issue? Thank you.

  from: "portus@xxxxx"
  name: "Portus"
  reply_to: "portus-no-reply@xxxx"
  smtp:
    enabled: true
    address: "xxxxx"
    port: 25

ldap:
  enabled: true
  hostname: "xxxxx"
  port: 389
  method: "tls"
  base: "xxxxx"
  uid: "xxxxxx"
  authentication:
    enabled: true
    bind_dn: "xxxxx"
    password: "xxxx"

machine_fqdn:
  value: "xxxxxxx"

display_name:
  enabled: true

first_user_admin:
  enabled: true

delete:
  enabled: true
  contributors: false

gravatar:
  enabled: true

signup:
  enabled: false

check_ssl_usage:
  enabled: true

registry:
  jwt_expiration_time:
    value: 5

  catalog_page:
    value: 100

  timeout:
    value: 5

  read_timeout:
    value: 120

user_permission:
  change_visibility:
    enabled: true

  create_team:
    enabled: true

  manage_team:
    enabled: true

  create_namespace:
    enabled: true

  manage_namespace:
    enabled: true

  push_images:
    enabled: true

oauth:
  google_oauth2:
    enabled: false
  open_id:
    enabled: false
  github:
    enabled: false
  gitlab:
    enabled: false
  bitbucket:
    enabled: false

To give back to our community of developers, we looked at our database of thousands of projects and found the top 10 errors in Ruby on Rails projects. We’re going to show you what causes them and how to prevent them from happening. If you avoid these «gotchas,» it’ll make you a better developer.

Because data is king, we collected, analyzed, and ranked the top 10 Ruby errors from Ruby on Rails applications. Rollbar collects all the errors for each project and summarizes how many times each one occurred. We do this by grouping errors according to fingerprinting. Basically, we group two errors if the second one is just a repeat of the first. This gives users a nice overview instead of an overwhelmingly big dump like you’d see in a log file.

We focused on the errors most likely to affect you and your users. To do this, we ranked errors by the number of projects experiencing them across different companies. We intentionally looked at the number of projects so that high-volume customers wouldn’t overwhelm the data set with errors that are not relevant to most readers.

Here are the top 10 Rails errors:

Screenshot of Rails Error Statistics

You’ve probably noticed some familiar faces in there already. Let’s dig in and take a look at the errors in a bit more detail to see what might cause them in your production application.

We’ll provide example solutions based on Rails 5, but if you’re still using Rails 4 they should point you in the right direction.

1. ActionController::RoutingError

We start with a classic of any web application, the Rails version of the 404 error. An ActionController::RoutingError means that a user has requested a URL that doesn’t exist within your application. Rails will log this and it will look like an error, but for the most part it is not the fault of your application.

It may be caused by incorrect links pointing at or from within your application. It may also be a malicious user or bot testing your application for common weaknesses. If that’s the case, you might find something like this in your logs:

ActionController::RoutingError (No route matches [GET] "/wp-admin"):

There is one common reason you might get an ActionController::RoutingError that is caused by your application and not by errant users: if you deploy your application to Heroku, or any platform that doesn’t allow you to serve static files, then you might find that your CSS and JavaScript doesn’t load. If this is the case, the errors will look like this:

ActionController::RoutingError (No route matches [GET] "//cdn.rollbar.com/assets/application-eff78fd93759795a7be3aa21209b0bd2.css"):

To fix this and allow Rails to serve static assets you need to add a line to your application’s config/environments/production.rb file:

Rails.application.configure do
  # other config
  config.public_file_server.enabled = true
end

If you aren’t interested in logging 404 errors caused by ActionController::RoutingError then you can avoid them by setting a catch all route and serving the 404 yourself. This method is suggested by the lograge project . To do so, add the following at the bottom of your config/routes.rb file:

Rails.application.routes.draw do
  # all your other routes
  match '*unmatched', to: 'application#route_not_found', via: :all
end

Then add the route_not_found method to your ApplicationController:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  def route_not_found
    render file: Rails.public_path.join('404.html'), status: :not_found, layout: false
  end
end

Before implementing this, you should consider whether knowing about 404 errors is important to you. You should also keep in mind that any route or engine that is mounted after the application loads won’t be reachable as they will be caught by the catch all route.

2. NoMethodError: undefined method ‘[]’ for nil:NilClass

This means that you are using square bracket notation to read a property from an object, but the object is missing, or nil, and thus it does not support this method. Since we are working with square brackets, it’s likely that we’re digging through hashes or arrays to access properties and something along the way was missing. This could happen when you’re parsing and extracting data from a JSON API or a CSV file, or just getting data from nested parameters in a controller action.

Consider a user submitting address details through a form. You might expect your parameters to look like this:

{ user: { address: { street: '123 Fake Street', town: 'Faketon', postcode: '12345' } } }

You might then access the street by calling params[:user][:address][:street]. If no address was passed then params[:user][:address] would be nil and calling for [:street] would raise a NoMethodError.

You could perform a nil check on each parameter and return early using the && operator, like so:

street = params[:user] && params[:user][:address] && params[:user][:address][:street]

While that will do the job, thankfully there is now a better way to access nested elements in hashes, arrays and event objects like ActionController::Parameters. Since Ruby 2.3, hashes, arrays and ActionController::Parameters have the dig method. dig allows you to provide a path to the object you want to retrieve. If at any stage nil is returned, then dig returns nil without throwing a NoMethodError. To get the street from the parameters above you can call:

street = params.dig(:user, :address, :street)

You won’t get any errors from this, though you do need to be aware that street may still be nil.

As an aside, if you are also digging through nested objects using dot notation, you can do this safely in Ruby 2.3 too, using the safe navigation operator. So, rather than calling

street = user.address.street

and getting a NoMethodError: undefined method street for nil:NilClass, you can now call.

street = user&.address&.street

The above will now act the same as using dig. If the address is nil then street will be nil and you will need to handle the nil when you later refer to the street. If all the objects are present, street will be assigned correctly.

While this suppresses errors from being shown to the user, if it still impacts user experience, you might want to create an internal error to track either in your logs or in an error tracking system like Rollbar so you have visibility to fix the problem.

If you are not using Ruby 2.3 or above you can achieve the same as above using the ruby_dig gem and ActiveSupport’s try to achieve similar results.

3. ActionController::InvalidAuthenticityToken

Number 3 on our list requires careful consideration as it is related to our application’s security. ActionController::InvalidAuthenticityToken will be raised when a POST, PUT, PATCH, or DELETE request is missing or has an incorrect CSRF (Cross Site Request Forgery) token.

CSRF is a potential vulnerability in web applications in which a malicious site makes a request to your application on behalf of an unaware user. If the user is logged in their session cookies will be sent along with the request and the attacker can execute commands as the user.

Rails mitigates CSRF attacks by including a secure token in all forms that is known and verified by the site, but can’t be known by a third party. This is performed by the familiar ApplicationController line

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end

So, if your production application is raising ActionController::InvalidAuthenticityToken errors it could mean that an attacker is targeting the users of your site, but the Rails security measures are keeping you safe.

There are other reasons you may be unintentionally receiving this error though.

Ajax

For example, if you are making Ajax requests from your front end, you need to ensure you are including the CSRF token within the request. If you are using jQuery and the built in Rails unobtrusive scripting adapter then this is already handled for you. If you want to handle Ajax another way, say using the Fetch API, you’ll need to ensure you include the CSRF token. For either approach, you need to make sure your application layout includes the CSRF meta tag in the <head> of the document:

<%= csrf_meta_tags %>

This prints out a meta tag that looks like this:

<meta name='csrf-token' content='THE-TOKEN'>

When making an Ajax request, read the meta tag content and add it to the headers as the X-CSRF-Token header.

const csrfToken = document.querySelector('[name="csrf-token"]').getAttribute('content');
fetch('/posts', {
  method: 'POST',
  body: JSON.stringify(body),
  headers: {
    'Content-Type': 'application/json'
    'X-CSRF-Token': csrfToken
  }
).then(function(response) {
  // handle response
});

Webhooks/APIs

Sometimes there are valid reasons to turn off the CSRF protection. If you expect to receive incoming POST requests to certain URLs in your application from third parties, you won’t want to block them on the basis of CSRF. You might be in this position if you are building an API for third party developers or if you expect to receive incoming webhooks from a service.

You can turn off CSRF protection, but make sure you are whitelisting the endpoints you know don’t need this kind of protection. You can do so in a controller by skipping the authentication:

class ApiController < ApplicationController
  skip_before_action :verify_authenticity_token
end

If you are accepting incoming webhooks, you should be able to verify that the request came from a trusted source in place of verifying the CSRF token.

4. Net::ReadTimeout

The Net::ReadTimeout is raised when it takes Ruby longer to read data from a socket than the read_timeout value, which is 60 seconds by default. This error can be raised if you are using Net::HTTP, open-uri or HTTParty to make HTTP requests.

Notably, this doesn’t mean that an error will be thrown if the request itself takes longer than the read_timeout value, just that if a particular read takes longer than the read_timeout. You can read more about Net::HTTP and timeouts from Felipe Philipp.

There are a couple of things we can do to stop getting Net::ReadTimeout errors. Once you understand the HTTP requests that are throwing the error you can try to adjust the read_timeout value to something more sensible. As in the article above, if the server you are making the request to takes a long time to put together a response before sending it all at once, you will want a longer read_timeout value. If the server returns the response in chunks then you will want a shorter read_timeout.

You can set read_timeout by setting a value in seconds on the respective HTTP client you are using:

with Net::HTTP

http = Net::HTTP.new(host, port, read_timout: 10)

with open-uri

open(url, read_timeout: 10)

with HTTParty

HTTParty.get(url, read_timeout: 10)

You can’t always trust another server to respond within your expected timeouts. If you can run the HTTP request in a background job with retries, like Sidekiq, that can mitigate the errors from the other server. You will need to handle the case where the server never responds in time though.

If you need to run the HTTP request within a controller action, then you should be rescuing the Net::ReadTimeout error and providing your user with an alternative experience and tracking it in your error monitoring solution. For example:

def show
  @post = Post.find(params[:slug])
  begin
    @comments = HTTParty.get(COMMENTS_SERVER, read_timeout: 10)
  rescue Net::ReadTimeout => e
    @comments = []
  @error_message = "Comments couldn't be retrieved, please try again later."
    Rollbar.error(e);
  end
end

5. ActiveRecord::RecordNotUnique: PG::UniqueViolation

This error message is specifically for PostgreSQL databases, but the ActiveRecord adapters for MySQL and SQLite will throw similar errors. The issue here is that a database table in your application has a unique index on one or more fields and a transaction has been sent to the database that violates that index. This is a hard problem to solve completely, but let’s look at the low hanging fruit first.

Imagine you’ve created a User model and, in the migration, ensured that the user’s email address is unique. The migration might look like this:

class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :email
      t.timestamps
    end
    add_index :users, :email, unique: true
  end
end

To avoid most instances of ActiveRecord::RecordNotUnique you should add a uniqueness validation to your User model too.

class User < ApplicationRecord
  validates_uniqueness_of :email
end

Without this validation, all email addresses will be sent to the database when calling User#save and will raise an error if they aren’t unique. However, the validation can’t guarantee that this won’t happen. For a full explanation you should read the concurrency and integrity section of the validates_uniqueness_of documentation. The quick description is that the Rails uniqueness check is prone to race conditions based on the order of operation for multiple requests. Being a race condition, this also makes this error hard to reproduce locally.

To deal with this error requires some context. If the errors are caused by a race condition, that may be because a user has submitted a form twice by mistake. We can try to mitigate that issue with a bit of JavaScript to disable the submit button after the first click. Something a bit like this is a start:

const forms = document.querySelectorAll('form');
Array.from(forms).forEach((form) => {
  form.addEventListener('submit', (event) => {
    const buttons = form.querySelectorAll('button, input[type=submit]')
    Array.from(buttons).forEach((button) => {
      button.setAttribute('disabled', 'disabled');
    });
  });
});

This tip on Coderwall to use ActiveRecord’s first_or_create! along with a rescue and retry when the error is raised is a neat workaround. You should continue to log the error with your error monitoring solution so that you maintain visibility on it.

def self.set_flag( user_id, flag )
  # Making sure we only retry 2 times
  tries ||= 2
  flag = UserResourceFlag.where( :user_id => user_id , :flag => flag).first_or_create!
rescue ActiveRecord::RecordNotUnique => e
  Rollbar.error(e)
  retry unless (tries -= 1).zero?
end

ActiveRecord::RecordNotUnique might seem like an edge case, but it’s here at number 5 in this top 10, so it is definitely worth considering with regard to your user experience.

6. NoMethodError: undefined method ‘id’ for nil:NilClass

NoMethodError appears again, though this time with a different explanatory message. This error usually sneaks up around the create action for an object with a relation. The happy path—creating the object successfully—usually works, but this error pops up when validations fail. Let’s take a look at an example.

Here’s a controller with actions to create an application for a course.

class CourseApplicationsController < ApplicationController
  def new
    @course_application = CourseApplication.new
    @course = Course.find(params[:course_id])
  end
  def create
    @course_application = CourseApplication.new(course_application_params)
    if @course_application.save
      redirect_to @course_application, notice: 'Application submitted'
    else
      render :new
    end
  end
  private
  def course_application_params
    params.require(:course_application).permit(:name, :email, :course_id)
  end
end

The form in the new template looks a bit like this:

<%= form_for [@course, @course_application] do |ca| %>
  <%# rest of the form %>
<% end %>

The problem here is when you call render :new from the create action, the @course instance variable wasn’t set. You need to ensure that all the objects the new template needs are initialised in the create action as well. To fix this error, we’d update the create action to look like this:

  def create
    @course_application = CourseApplication.new(course_application_params)
    if @course_application.save
      redirect_to @course_application, notice: 'Application submitted'
    else
      @course = Course.find(params[:course_id])
      render :new
    end
  end

Check out this article if you are interested in learning more about the problems with nil in Rails and how to avoid them.

7. ActionController::ParameterMissing

This error is part of the Rails strong parameters implementation. It does not manifest as a 500 error though—it is rescued by ActionController::Base and returned as a 400 Bad Request.

The full error might look like this:

ActionController::ParameterMissing: param is missing or the value is empty: user

This will be accompanied by a controller that might look a bit like this:

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render :new
    end
  end
  private
  def user_params
    params.require(:user).permit(:name, :email)
  end
end

The params.require(:user) means that if user_params is called and params does not have a :user key or params[:user] is empty, ActionController::ParameterMissing will be raised.

If you are building an application to be used via a web front end and you have built a form to correctly post the user parameters to this action, then a missing user parameter probably means someone is messing with your application. If that is the case, a 400 Bad Request response is likely the best response as you don’t need to cater to potentially malicious users.

If your application is providing an API, then 400 Bad Request is also an appropriate response to a missing parameter.

8. ActionView::Template::Error: undefined local variable or method

This is our only ActionView error in the top 10 and that’s a good sign. The less work the views have to do to render templates the better. Less work leads to fewer errors. We’re still left with this error though, in which a variable or method you expect to exist simply doesn’t.

This crops up most commonly in partials, probably due to the many different ways you can include a partial with local variables on a page. If you have a partial called _post.html.erb that contains a blog post template and an instance variable @post set in your controller, then you can render the partial like this:

<%= render @post %>

or

<%= render 'post', post: @post %>

or

<%= render partial: 'post', locals: { post: @post } %>

Rails likes to give us plenty of options to work with, but the second and third options here are where confusion can creep in. Trying to render a partial like:

<%= render 'post', locals: { post: @post } %>

or

<%= render partial: 'post', post: @post %>

will leave you with an undefined local variable or method. To avoid this, stay consistent and always render partials with the explicit partial syntax, expressing the local variables in a locals hash:

<%= render partial: 'post', locals: { post: @post } %>

There is one other place you can slip up with local variables in partials. If you only sometimes pass a variable to a partial, testing for that variable is different within a partial to regular Ruby code. If, for example, you update the post partial above to take a local variable that tells you whether to show a header image in the partial, you would render the partial like so:

<%= render partial: 'post', locals: { post: @post, show_header_image: true } %>

Then the partial itself might look like this:

<h1><%= @post.title %></h1>
<%= image_tag(@post.header_image) if show_header_image %>
<!-- and so on -->

This will work fine when you pass the show_header_image local variable, but when you call

<%= render partial: 'post', locals: { post: @post } %>

it will fail with an undefined local variable. To test for the existence of a local variable inside a partial, you should check whether it is defined before you use it.

<%= image_tag(@post.header_image) if defined?(show_header_image) && show_header_image %>

Even better though, there is a hash called local_assigns within a partial that we can use instead.

<%= image_tag(@post.header_image) if local_assigns[:show_header_image] %>

For variables that aren’t booleans, we can use other hash methods like fetch to handle this gracefully. Using show_header_image as an example, this scenario would also work:

<%= image_tag(@post.header_image) if local_assigns.fetch(:show_header_image, false) %>

Overall, watch out when you are passing variables to partials!

9. ActionController::UnknownFormat

This error, like the ActionController::InvalidAuthenticityToken, is one that could be caused by careless or malicious users rather than your application. If you’ve built an application in which the actions respond with HTML templates and someone requests the JSON version of the page, you will find this error in your logs, looking a bit like this:

ActionController::UnknownFormat (BlogPostsController#index is missing a template for this request format and variant.
request.formats: ["application/json"]
request.variant: []):

The user will receive a 406 Not Acceptable response. In this case they’ll see this error because you haven’t defined a template for this response. This is a reasonable response, since if you don’t want to return JSON, their request was not acceptable.

You may, however, have built your Rails application to respond to regular HTML requests and more API-like JSON requests in the same controller. Once you start doing this, you define the formats you do want to respond to and any formats that fall outside of that will also cause an ActionController::UnknownFormat, returning a 406 status. Let’s say you have a blog posts index that looks like:

class BlogPostsController < ApplicationController
  def index
    respond_to do |format|
      format.html { render :index }
    end
  end
end

Making a request for the JSON would result in the 406 response and your logs would show this less expressive error:

ActionController::UnknownFormat (ActionController::UnknownFormat):

The error this time doesn’t complain about a lack of a template—it’s an intentional error because you have defined the only format to respond to is HTML. What if this is unintentional though?

It’s common to miss a format in a response that you intend to support. Consider an action in which you want to respond to HTML and JSON requests when creating a blog post, so that your page can support an Ajax request. It might look like this:

class BlogPostsController < ApplicationController
  def create
    @blog_post = BlogPost.new(blog_post_params)
    respond_to do |format|
      if @blog_post.save
        format.html { redirect blog_post_path(@blog_post) }
        format.json { render json: @blog_post.to_json }
      else
        render :new
      end
    end
  end
end

The error here is raised in the case of the blog post failing validations and not saving. Within the respond_to block, you need to call render within the scope of the format blocks. Rewriting this to accommodate for failure would look like:

class BlogPostsController < ApplicationController
  def create
    @blog_post = BlogPost.new(blog_post_params)
    respond_to do |format|
      if @blog_post.save
        format.html { redirect blog_post_path(@blog_post) }
        format.json { render json: @blog_post.to_json }
      else
        format.html { render :new }
        format.json { render json: @blog_post.errors.to_json }
      end
    end
  end
end

Now all of the formats are covered and there won’t be any more unintentional ActionController::UnknownFormat exceptions.

10. StandardError: An error has occurred, this and all later migrations canceled

This last item on our top 10 disappoints me slightly. StandardError is the base error class that all other errors should inherit from, so using it here makes the error feel very generic, when in reality it is an error that has happened during a database migration. I would prefer to see this error as a descendent of the ActiveRecord::MigrationError. But I digress…

There are a number of things that can cause a migration to fail. Your migrations may have gotten out of sync with your actual production database, for example. In that case, you’re going to have to go digging around to find out what has happened and fix it.

There is one thing that should be covered here though: data migrations.

If you need to add or calculate some data for all the objects in a table you might think that a data migration is a good idea. As an example, if you wanted to add a full name field to a user model that included their first and last name (not a likely change, but good enough for a simple example), you might write a migration like this:

class AddFullNameToUser < ActiveRecord::Migration
  def up
    add_column :users, :full_name, :string
    User.find_each do |user|
      user.full_name = "#{user.first_name} #{user.last_name}"
      user.save!
    end
  end
  def down
    remove_column :users, :full_name
  end
end

There are a lot of problems with this scenario. If there is a user with corrupt data in y x xour set, the user.save! command will throw an error and cancel the migration. Secondly, in production you may have a lot of users, which means the database would take a long time to migrate, possibly keeping your application offline for the entire time. Finally, as your application changes over time, you might remove or rename the User model, which would cause this migration to fail. Some advice suggests that you define a User model within the migration to avoid this. For even greater safety, Elle Meredith advises us to avoid data migrations within ActiveRecord migrations completely and build out temporary data migration tasks instead.

Changing data outside of the migration ensures you do a few things. Most importantly, it makes you consider how your model works if the data is not present. In our full name example, you would likely define an accessor for the full_name property that could respond if the data was available. If it’s not, then build the full name by concatenating the constituent parts.

class User < ApplicationRecord
  def full_name
    @full_name || "#{first_name} #{last_name}"
  end
end

Running a data migration as a separate task also means the deploy no longer relies on this data changing across the production database. Elle’s article has more reasons why this works better and includes best practices on writing the task as well.

Conclusion

The most popular Rails errors can come from anywhere within the application. In this article we’ve seen common errors manifested in the model, the view, and the controller. Some of the errors aren’t necessarily anything to worry about and are just protecting your application. Others should be caught as soon as possible and stamped out.

Nevertheless, it’s good to track how often these errors happen. This leads to better visibility into problems that are affecting your users or application security, so you can fix them quickly. Otherwise, these error messages will be shown to the user, but the engineering and product management teams will have no idea until users complain to support.

We hope you learned something new and are better equipped to avoid these errors in the future. However, even with the best practices, unexpected errors do pop up in production. It’s important to have visibility into errors that affect your users, and to have good tools to solve them quickly.

Rollbar gives you visibility to production Ruby errors, which offers more context to solve them quickly, including form validation errors, person tracking, boot errors and more. Check out Rollbar’s full list of features and Ruby SDK documentation.


If you haven’t already, sign up for a 14-day free trial of Rollbar and let us help you take control of impactful Rails errors.

Содержание

  1. NoMethodError: undefined method for nil:NilClass. Explained
  2. Top comments (6)
  3. Top 10 errors from 1000+ Ruby on Rails projects (and how to avoid them)
  4. Here are the top 10 Rails errors:
  5. 1. ActionController::RoutingError
  6. 2. NoMethodError: undefined method ‘[]’ for nil:NilClass
  7. 3. ActionController::InvalidAuthenticityToken
  8. Webhooks/APIs
  9. 4. Net::ReadTimeout
  10. 5. ActiveRecord::RecordNotUnique: PG::UniqueViolation
  11. 6. NoMethodError: undefined method ‘id’ for nil:NilClass
  12. 7. ActionController::ParameterMissing
  13. 8. ActionView::Template::Error: undefined local variable or method
  14. 9. ActionController::UnknownFormat
  15. 10. StandardError: An error has occurred, this and all later migrations canceled
  16. Conclusion

NoMethodError: undefined method for nil:NilClass. Explained

This is a common Ruby error which indicates that the method or attribute for an object you are trying to call on an object has not been defined.

Exit fullscreen mode

For example, the String class in Ruby has the method size (which is synonymous with length , so I can write.

Exit fullscreen mode

But loveliness does not exist for a string, so when I type it, I will get.

Exit fullscreen mode

I find this will come up when I think I’m operating on an object with methods, but I’m actually operating on a hash with attributes.

Exit fullscreen mode

Of course, because this is Ruby, we can actually define loveliness if we wanted to very easily by monkeypatching the String class.

Exit fullscreen mode

Now we know how lovely our string is. If I was mistaken or unclear, please feel free to add a comment to clarify anything here.

This one tripped up me all the time when I was just starting out. While the error seems to be about the method, it’s usually the object you’re trying to call it on that is problematic somehow.

If the object is allowed to be nil, you want to check its presence before calling any method on it. For example:

Exit fullscreen mode

Or if you like concise code:

Exit fullscreen mode

Small nitpick about the example code in article: if my_hash was an actual hash, the error would say <:foo =>:bar>:Hash instead of nil:NilClass .

Haha. Very basic but pesky one for beginners.
I can say nearly one third of SO questions are javascript version of this problem.

Undefined is not a function

yikes. what a mess, the more i work with ruby and search for these kinds of issues, the less thrilled i am with the design of the language

I’m actually being shown this error when I try to save an article here in dev.to . ironic

For further actions, you may consider blocking this person and/or reporting abuse

We’re hiring for a Senior Platform Engineer and would love for you to apply.

Head here to learn more about who we’re looking for.

Источник

Top 10 errors from 1000+ Ruby on Rails projects (and how to avoid them)

Table of Contents

To give back to our community of developers, we looked at our database of thousands of projects and found the top 10 errors in Ruby on Rails projects. We’re going to show you what causes them and how to prevent them from happening. If you avoid these «gotchas,» it’ll make you a better developer.

Because data is king, we collected, analyzed, and ranked the top 10 Ruby errors from Ruby on Rails applications. Rollbar collects all the errors for each project and summarizes how many times each one occurred. We do this by grouping errors according to fingerprinting. Basically, we group two errors if the second one is just a repeat of the first. This gives users a nice overview instead of an overwhelmingly big dump like you’d see in a log file.

We focused on the errors most likely to affect you and your users. To do this, we ranked errors by the number of projects experiencing them across different companies. We intentionally looked at the number of projects so that high-volume customers wouldn’t overwhelm the data set with errors that are not relevant to most readers.

Here are the top 10 Rails errors:

You’ve probably noticed some familiar faces in there already. Let’s dig in and take a look at the errors in a bit more detail to see what might cause them in your production application.

We’ll provide example solutions based on Rails 5, but if you’re still using Rails 4 they should point you in the right direction.

1. ActionController::RoutingError

We start with a classic of any web application, the Rails version of the 404 error. An ActionController::RoutingError means that a user has requested a URL that doesn’t exist within your application. Rails will log this and it will look like an error, but for the most part it is not the fault of your application.

It may be caused by incorrect links pointing at or from within your application. It may also be a malicious user or bot testing your application for common weaknesses. If that’s the case, you might find something like this in your logs:

There is one common reason you might get an ActionController::RoutingError that is caused by your application and not by errant users: if you deploy your application to Heroku, or any platform that doesn’t allow you to serve static files, then you might find that your CSS and JavaScript doesn’t load. If this is the case, the errors will look like this:

To fix this and allow Rails to serve static assets you need to add a line to your application’s config/environments/production.rb file:

If you aren’t interested in logging 404 errors caused by ActionController::RoutingError then you can avoid them by setting a catch all route and serving the 404 yourself. This method is suggested by the lograge project . To do so, add the following at the bottom of your config/routes.rb file:

Then add the route_not_found method to your ApplicationController :

Before implementing this, you should consider whether knowing about 404 errors is important to you. You should also keep in mind that any route or engine that is mounted after the application loads won’t be reachable as they will be caught by the catch all route.

2. NoMethodError: undefined method ‘[]’ for nil:NilClass

This means that you are using square bracket notation to read a property from an object, but the object is missing, or nil , and thus it does not support this method. Since we are working with square brackets, it’s likely that we’re digging through hashes or arrays to access properties and something along the way was missing. This could happen when you’re parsing and extracting data from a JSON API or a CSV file, or just getting data from nested parameters in a controller action.

Consider a user submitting address details through a form. You might expect your parameters to look like this:

You might then access the street by calling params[:user][:address][:street] . If no address was passed then params[:user][:address] would be nil and calling for [:street] would raise a NoMethodError .

You could perform a nil check on each parameter and return early using the && operator, like so:

While that will do the job, thankfully there is now a better way to access nested elements in hashes, arrays and event objects like ActionController::Parameters . Since Ruby 2.3, hashes, arrays and ActionController::Parameters have the dig method. dig allows you to provide a path to the object you want to retrieve. If at any stage nil is returned, then dig returns nil without throwing a NoMethodError . To get the street from the parameters above you can call:

You won’t get any errors from this, though you do need to be aware that street may still be nil .

As an aside, if you are also digging through nested objects using dot notation, you can do this safely in Ruby 2.3 too, using the safe navigation operator. So, rather than calling

and getting a NoMethodError: undefined method street for nil:NilClass , you can now call.

The above will now act the same as using dig . If the address is nil then street will be nil and you will need to handle the nil when you later refer to the street . If all the objects are present, street will be assigned correctly.

While this suppresses errors from being shown to the user, if it still impacts user experience, you might want to create an internal error to track either in your logs or in an error tracking system like Rollbar so you have visibility to fix the problem.

If you are not using Ruby 2.3 or above you can achieve the same as above using the ruby_dig gem and ActiveSupport’s try to achieve similar results.

3. ActionController::InvalidAuthenticityToken

Number 3 on our list requires careful consideration as it is related to our application’s security. ActionController::InvalidAuthenticityToken will be raised when a POST, PUT, PATCH, or DELETE request is missing or has an incorrect CSRF (Cross Site Request Forgery) token.

CSRF is a potential vulnerability in web applications in which a malicious site makes a request to your application on behalf of an unaware user. If the user is logged in their session cookies will be sent along with the request and the attacker can execute commands as the user.

Rails mitigates CSRF attacks by including a secure token in all forms that is known and verified by the site, but can’t be known by a third party. This is performed by the familiar ApplicationController line

So, if your production application is raising ActionController::InvalidAuthenticityToken errors it could mean that an attacker is targeting the users of your site, but the Rails security measures are keeping you safe.

There are other reasons you may be unintentionally receiving this error though.

For example, if you are making Ajax requests from your front end, you need to ensure you are including the CSRF token within the request. If you are using jQuery and the built in Rails unobtrusive scripting adapter then this is already handled for you. If you want to handle Ajax another way, say using the Fetch API, you’ll need to ensure you include the CSRF token. For either approach, you need to make sure your application layout includes the CSRF meta tag in the of the document:

This prints out a meta tag that looks like this:

When making an Ajax request, read the meta tag content and add it to the headers as the X-CSRF-Token header.

Webhooks/APIs

Sometimes there are valid reasons to turn off the CSRF protection. If you expect to receive incoming POST requests to certain URLs in your application from third parties, you won’t want to block them on the basis of CSRF. You might be in this position if you are building an API for third party developers or if you expect to receive incoming webhooks from a service.

You can turn off CSRF protection, but make sure you are whitelisting the endpoints you know don’t need this kind of protection. You can do so in a controller by skipping the authentication:

If you are accepting incoming webhooks, you should be able to verify that the request came from a trusted source in place of verifying the CSRF token.

4. Net::ReadTimeout

The Net::ReadTimeout is raised when it takes Ruby longer to read data from a socket than the read_timeout value, which is 60 seconds by default. This error can be raised if you are using Net::HTTP , open-uri or HTTParty to make HTTP requests.

Notably, this doesn’t mean that an error will be thrown if the request itself takes longer than the read_timeout value, just that if a particular read takes longer than the read_timeout . You can read more about Net::HTTP and timeouts from Felipe Philipp.

There are a couple of things we can do to stop getting Net::ReadTimeout errors. Once you understand the HTTP requests that are throwing the error you can try to adjust the read_timeout value to something more sensible. As in the article above, if the server you are making the request to takes a long time to put together a response before sending it all at once, you will want a longer read_timeout value. If the server returns the response in chunks then you will want a shorter read_timeout .

You can set read_timeout by setting a value in seconds on the respective HTTP client you are using:

with Net::HTTP

with open-uri

with HTTParty

You can’t always trust another server to respond within your expected timeouts. If you can run the HTTP request in a background job with retries, like Sidekiq, that can mitigate the errors from the other server. You will need to handle the case where the server never responds in time though.

If you need to run the HTTP request within a controller action, then you should be rescuing the Net::ReadTimeout error and providing your user with an alternative experience and tracking it in your error monitoring solution. For example:

5. ActiveRecord::RecordNotUnique: PG::UniqueViolation

This error message is specifically for PostgreSQL databases, but the ActiveRecord adapters for MySQL and SQLite will throw similar errors. The issue here is that a database table in your application has a unique index on one or more fields and a transaction has been sent to the database that violates that index. This is a hard problem to solve completely, but let’s look at the low hanging fruit first.

Imagine you’ve created a User model and, in the migration, ensured that the user’s email address is unique. The migration might look like this:

To avoid most instances of ActiveRecord::RecordNotUnique you should add a uniqueness validation to your User model too.

Without this validation, all email addresses will be sent to the database when calling User#save and will raise an error if they aren’t unique. However, the validation can’t guarantee that this won’t happen. For a full explanation you should read the concurrency and integrity section of the validates_uniqueness_of documentation. The quick description is that the Rails uniqueness check is prone to race conditions based on the order of operation for multiple requests. Being a race condition, this also makes this error hard to reproduce locally.

To deal with this error requires some context. If the errors are caused by a race condition, that may be because a user has submitted a form twice by mistake. We can try to mitigate that issue with a bit of JavaScript to disable the submit button after the first click. Something a bit like this is a start:

This tip on Coderwall to use ActiveRecord’s first_or_create! along with a rescue and retry when the error is raised is a neat workaround. You should continue to log the error with your error monitoring solution so that you maintain visibility on it.

ActiveRecord::RecordNotUnique might seem like an edge case, but it’s here at number 5 in this top 10, so it is definitely worth considering with regard to your user experience.

6. NoMethodError: undefined method ‘id’ for nil:NilClass

NoMethodError appears again, though this time with a different explanatory message. This error usually sneaks up around the create action for an object with a relation. The happy path—creating the object successfully—usually works, but this error pops up when validations fail. Let’s take a look at an example.

Here’s a controller with actions to create an application for a course.

The form in the new template looks a bit like this:

The problem here is when you call render :new from the create action, the @course instance variable wasn’t set. You need to ensure that all the objects the new template needs are initialised in the create action as well. To fix this error, we’d update the create action to look like this:

Check out this article if you are interested in learning more about the problems with nil in Rails and how to avoid them.

7. ActionController::ParameterMissing

This error is part of the Rails strong parameters implementation. It does not manifest as a 500 error though—it is rescued by ActionController::Base and returned as a 400 Bad Request.

The full error might look like this:

This will be accompanied by a controller that might look a bit like this:

The params.require(:user) means that if user_params is called and params does not have a :user key or params[:user] is empty, ActionController::ParameterMissing will be raised.

If you are building an application to be used via a web front end and you have built a form to correctly post the user parameters to this action, then a missing user parameter probably means someone is messing with your application. If that is the case, a 400 Bad Request response is likely the best response as you don’t need to cater to potentially malicious users.

If your application is providing an API, then 400 Bad Request is also an appropriate response to a missing parameter.

8. ActionView::Template::Error: undefined local variable or method

This is our only ActionView error in the top 10 and that’s a good sign. The less work the views have to do to render templates the better. Less work leads to fewer errors. We’re still left with this error though, in which a variable or method you expect to exist simply doesn’t.

This crops up most commonly in partials, probably due to the many different ways you can include a partial with local variables on a page. If you have a partial called _post.html.erb that contains a blog post template and an instance variable @post set in your controller, then you can render the partial like this:

Rails likes to give us plenty of options to work with, but the second and third options here are where confusion can creep in. Trying to render a partial like:

will leave you with an undefined local variable or method. To avoid this, stay consistent and always render partials with the explicit partial syntax, expressing the local variables in a locals hash:

There is one other place you can slip up with local variables in partials. If you only sometimes pass a variable to a partial, testing for that variable is different within a partial to regular Ruby code. If, for example, you update the post partial above to take a local variable that tells you whether to show a header image in the partial, you would render the partial like so:

Then the partial itself might look like this:

This will work fine when you pass the show_header_image local variable, but when you call

it will fail with an undefined local variable. To test for the existence of a local variable inside a partial, you should check whether it is defined before you use it.

Even better though, there is a hash called local_assigns within a partial that we can use instead.

For variables that aren’t booleans, we can use other hash methods like fetch to handle this gracefully. Using show_header_image as an example, this scenario would also work:

Overall, watch out when you are passing variables to partials!

9. ActionController::UnknownFormat

This error, like the ActionController::InvalidAuthenticityToken , is one that could be caused by careless or malicious users rather than your application. If you’ve built an application in which the actions respond with HTML templates and someone requests the JSON version of the page, you will find this error in your logs, looking a bit like this:

The user will receive a 406 Not Acceptable response. In this case they’ll see this error because you haven’t defined a template for this response. This is a reasonable response, since if you don’t want to return JSON, their request was not acceptable.

You may, however, have built your Rails application to respond to regular HTML requests and more API-like JSON requests in the same controller. Once you start doing this, you define the formats you do want to respond to and any formats that fall outside of that will also cause an ActionController::UnknownFormat , returning a 406 status. Let’s say you have a blog posts index that looks like:

Making a request for the JSON would result in the 406 response and your logs would show this less expressive error:

The error this time doesn’t complain about a lack of a template—it’s an intentional error because you have defined the only format to respond to is HTML. What if this is unintentional though?

It’s common to miss a format in a response that you intend to support. Consider an action in which you want to respond to HTML and JSON requests when creating a blog post, so that your page can support an Ajax request. It might look like this:

The error here is raised in the case of the blog post failing validations and not saving. Within the respond_to block, you need to call render within the scope of the format blocks. Rewriting this to accommodate for failure would look like:

Now all of the formats are covered and there won’t be any more unintentional ActionController::UnknownFormat exceptions.

10. StandardError: An error has occurred, this and all later migrations canceled

This last item on our top 10 disappoints me slightly. StandardError is the base error class that all other errors should inherit from, so using it here makes the error feel very generic, when in reality it is an error that has happened during a database migration. I would prefer to see this error as a descendent of the ActiveRecord::MigrationError . But I digress…

There are a number of things that can cause a migration to fail. Your migrations may have gotten out of sync with your actual production database, for example. In that case, you’re going to have to go digging around to find out what has happened and fix it.

There is one thing that should be covered here though: data migrations.

If you need to add or calculate some data for all the objects in a table you might think that a data migration is a good idea. As an example, if you wanted to add a full name field to a user model that included their first and last name (not a likely change, but good enough for a simple example), you might write a migration like this:

There are a lot of problems with this scenario. If there is a user with corrupt data in y x xour set, the user.save! command will throw an error and cancel the migration. Secondly, in production you may have a lot of users, which means the database would take a long time to migrate, possibly keeping your application offline for the entire time. Finally, as your application changes over time, you might remove or rename the User model, which would cause this migration to fail. Some advice suggests that you define a User model within the migration to avoid this. For even greater safety, Elle Meredith advises us to avoid data migrations within ActiveRecord migrations completely and build out temporary data migration tasks instead.

Changing data outside of the migration ensures you do a few things. Most importantly, it makes you consider how your model works if the data is not present. In our full name example, you would likely define an accessor for the full_name property that could respond if the data was available. If it’s not, then build the full name by concatenating the constituent parts.

Running a data migration as a separate task also means the deploy no longer relies on this data changing across the production database. Elle’s article has more reasons why this works better and includes best practices on writing the task as well.

Conclusion

The most popular Rails errors can come from anywhere within the application. In this article we’ve seen common errors manifested in the model, the view, and the controller. Some of the errors aren’t necessarily anything to worry about and are just protecting your application. Others should be caught as soon as possible and stamped out.

Nevertheless, it’s good to track how often these errors happen. This leads to better visibility into problems that are affecting your users or application security, so you can fix them quickly. Otherwise, these error messages will be shown to the user, but the engineering and product management teams will have no idea until users complain to support.

We hope you learned something new and are better equipped to avoid these errors in the future. However, even with the best practices, unexpected errors do pop up in production. It’s important to have visibility into errors that affect your users, and to have good tools to solve them quickly.

Rollbar gives you visibility to production Ruby errors, which offers more context to solve them quickly, including form validation errors, person tracking, boot errors and more. Check out Rollbar’s full list of features and Ruby SDK documentation.

If you haven’t already, sign up for a 14-day free trial of Rollbar and let us help you take control of impactful Rails errors.

Источник

Я использую ruby 2.4 и rails 5.1.6.

Чтобы изучить RoR, я создал пользовательскую модель, представление и контроллер вручную, а не использовал строительные леса.

После заполнения формы для создания нового пользователя я получаю эту ошибку в журнале сервера rails:

Started POST "/users" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"gdSumxEvNi6ECKBZLFKN9dB/PYLOmixMcf5oYcUGkE1u4iAa/YkJlu7SJbPQNlh6J2SEzR2WeSUT9frhteEOCw==", "user"=>{"name"=>"User1", "email"=>"user1@yahoo.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign Up"}
   (0.2ms)  begin transaction
  User Exists (0.6ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "user1@yahoo.com"], ["LIMIT", 1]]
  SQL (0.8ms)  INSERT INTO "users" ("name", "email", "password_digest", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["name", "User1"], ["email", "user1@yahoo.com"], ["password_digest", "$2a$10$Efhs2Z2BRa5FCUdSIz6D5.c/eiFQm3JaW818veE644NdoWluRLjoq"], ["created_at", "2018-08-27 10:22:45.636574"], ["updated_at", "2018-08-27 10:22:45.636574"]]
   (1.0ms)  commit transaction
Redirected to http://127.0.0.1:3000/users/1
Completed 302 Found in 93ms (ActiveRecord: 2.6ms)


Started GET "/users/1" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}
  Rendering users/show.html.erb within layouts/application
  Rendered users/show.html.erb within layouts/application (9.8ms)
Completed 500 Internal Server Error in 32ms (ActiveRecord: 0.0ms)



ActionView::Template::Error (undefined method `name' for nil:NilClass):
    1: 
    2: <h1><%= @user.name %></h1>
    3: <h2><%= @user.email %></h2>

app/views/users/show.html.erb:2:in `_app_views_users_show_html_erb___1408287096995644504_70277415453360'

Как видите, запись успешно сохраняется в БД, но каким-то образом переменная @user уничтожается к тому времени, когда она попадает в шаблон show.html.erb.

Вот это users_controller.rb

class UsersController < ApplicationController
  def index
  end

  def show
    byebug
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
      byebug
    else
      render 'new'
    end
  end

  def edit
  end

  def update
  end

  def destroy
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end

… а вот содержимое show.html.erb

<h1><%= @user.name %></h1>
<h2><%= @user.email %></h2>

Вывод @ user.name в точке останова byebug в действии user # create показывает правильное значение, но во второй точке останова byebug в действии user # show я получаю эту ошибку:

(byebug) @user.name
*** NoMethodError Exception: undefined method `name' for nil:NilClass

Просто чтобы убедиться, я сделал второе приложение, но использовал генератор скаффолдов, и все работало нормально.

Любые идеи?

P.s.

Я написал несколько проверок в пользовательской модели (app / models / user.rb). Я включил это ниже на всякий случай …

class User < ApplicationRecord
    validates :name, presence: true
    VALID_EMAIL_REGEX = /A[w+-.]+@[a-zd-.]+.[a-z]+z/i
    before_save {email.downcase!}
    validates :email, presence: true, 
                        format: {with: VALID_EMAIL_REGEX},
                        uniqueness: {case_sensitive: false}

    validates :password, presence: true, length: {minimum: 6}

    has_secure_password
end

Вы должны определить метод установки в приватной области контроллера пользователя

private
def set_user
  @user = User.find(params[:id])
end

И добавьте это в контроллер:

before_action :set_user, only: [:show]

Вы также можете определить (в before_action) другие методы, которым требуется доступ к объекту пользователя.


1

benjy
27 Авг 2018 в 11:14

Если вы можете проверить свой журнал ниже заявление, упомянуто:

Started GET "/users/1" for 127.0.0.1 at 2018-08-27 15:52:45 +0530
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}

Хэш {«id» => «1»} указывает на то, что вы пытаетесь получить пользователя с id = 1. Теперь вам просто нужно переопределить метод show, как показано ниже:

  def show
    @user = User.find_by_id(params[:id])
  end


2

Cryptex Technologies
27 Авг 2018 в 11:09

Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Rendered employees/show.html.erb within layouts/application (110.6ms)
Completed 500 Internal Server Error in 116ms (ActiveRecord: 7.4ms)

ActionView::Template::Error (undefined method `name' for nil:NilClass):
    16:   <div class="entry">
    17:   <strong><%= entry.state %></strong>
    18:     <%= entry.time %>
    19:     <%= entry.account.name %>
    20:     <%= entry.created_at %>
    21:   </div>
    22: <% end %>

84 Answers

jitendra goyal March 8, 2016 11:02pm

Steve Hunter March 8, 2016 11:17pm

I’ve no idea if this is to do with the issue you have but you have double-defined a variable in your accounts_controller — I’m just cruising through your code looking for stuff that looks off; this is the first I found:

class AccountsController < ApplicationController
    def index
        @accounts  = Account.all # delete this line
        @accounts = Customer.all
    end

    def show
        @account = Account.find(params[:id])

    end
end

Point @accounts at the Customer; delete the Account line.

Let me know if that helps,

Steve.

jitendra goyal March 8, 2016 11:27pm

its not working Steve, i did the same as u said.

jitendra goyal March 8, 2016 11:37pm

I have four employees, when i click on first two employee name it gave me the error-

NoMethodError in Employees#show
Showing /Users/jitendragoyal/biller/app/views/employees/show.html.erb where line #19 raised:

undefined method `name’ for nil:NilClass
Extracted source (around line #19):

17 <strong><%= entry.state %></strong>
18  <%= entry.time %>
19  <%= entry.account.name %>
20 <%= entry.created_at %>
21  </div>
22 <% end %>

but when I click on the other two employees name it’s working.
i did everything, i have restarted the server many times.

Steve Hunter March 8, 2016 11:41pm

You have probably created the first two employees before adding functionality to the database. Delete the two causing a problem inside the irb console. Use rails c and go find those two employees and delete them, then replace them with new one that reflect the new structure you have created.

Steve.

jitendra goyal March 9, 2016 12:00am

i typed —
TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

jitendra goyal March 9, 2016 12:11am

ok.i deleted all the employees through the console and create a new employee.but problem is same

jitendra goyal March 9, 2016 12:12am

jitendra goyal March 9, 2016 12:20am

No problem Steve, you have to sleep.I’ll try to solve the problem.
thank you so much.

jitendra goyal March 9, 2016 11:32am

Still I have same problem. don’t know why?

jitendra goyal March 9, 2016 11:40am

This is my account.rb file code-

class Account < ActiveRecord::Base

has_many :account_entries, dependent: :destroy

validates :name, presence: true, 
                 length: {in: 1..70, 
                          message: "Please use a decent name, sir."}, 
                 uniqueness: true

validate :your_name_is_not_dumb

def your_name_is_not_dumb
    if name.include?("dumb")
        errors.add(:name, "is dumb")
    end
end

def update_balance!
    update_attributes( balance: self.account_entries.sum(:amount) )

end

end

jitendra goyal March 9, 2016 11:41am

I typed — TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

now the new error in rails console —

TimeEntry Load (0.9ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN (‘TimeEntry’) (0.3ms) BEGIN

Account Load (0.6ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1

SQL (2.1ms) UPDATE account_entries SET state = ‘submitted’, updated_at = ‘2016-03-08 23:46:15’ WHERE account_entries.id = 1 (2.6ms) ROLLBACK

NoMethodError: undefined method `update_balance!’ for nil:NilClass

jitendra goyal March 9, 2016 11:44am

Account.count

(37.7ms) SELECT COUNT(*) FROM accounts

=> 1576

jitendra goyal March 9, 2016 11:51am

Employee.first

Employee Load (168.0ms) SELECT accounts.* FROM accounts WHERE accounts.type IN (‘Employee’) ORDER BY accounts.id ASC LIMIT 1

=> #Employee id: 1582, type: «Employee», name: «jyoti», email: nil, about: nil, created_at: «2016-03-09 00:10:35», updated_at: «2016-03-09 00:10:35», city: nil, zipcode: nil, state: nil, employees: nil, balance: nil

jitendra goyal March 9, 2016 11:54am

jitendra goyal March 9, 2016 11:58am

Employee.count

(3.4ms) SELECT COUNT(*) FROM accounts WHERE accounts.type IN (‘Employee’)

=> 2

jitendra goyal March 9, 2016 11:58am

means output of this query is correct.I have only two employees.

jitendra goyal March 9, 2016 11:59am

My problem is when I typed — TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

now the new error in rails console —

TimeEntry Load (0.9ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN (‘TimeEntry’) (0.3ms) BEGIN

Account Load (0.6ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1

SQL (2.1ms) UPDATE account_entries SET state = ‘submitted’, updated_at = ‘2016-03-08 23:46:15’ WHERE account_entries.id = 1 (2.6ms) ROLLBACK

NoMethodError: undefined method `update_balance!’ for nil:NilClass

jitendra goyal March 9, 2016 12:01pm

TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

This query is not working.

jitendra goyal March 9, 2016 12:02pm

If u need some file code of this project Ill send it to u.

jitendra goyal March 9, 2016 12:04pm

jitendra goyal March 9, 2016 12:10pm

jitendra goyal March 9, 2016 12:21pm

All the query is working correctly in console except-
TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

jitendra goyal March 9, 2016 12:22pm

Means problem is still same.I can’t figure out the problem…

Steve Hunter March 9, 2016 12:30pm

OK, so the problem is when operating on the account_entries.id. It sees the method update_balance as undefined. That’s not the case, as we know, it is in your code. The issue is that the method is undefined for an object of nil::NilClass. So the issue is, again, the account entry, or account, pulling back a nil.

Walking through the code, the update_balance! method is held in the account model but it is called from the account_entry model via its own customer method, update_account_balance. Inside that method, it calls account.update_balance!. That’s where it fails but that doesn’t mean the lack of account stems from there. That could happen anywhere, annoyingly. I wonder if the lack of saving of the account instance at that point would cause it to drop the instance?

Worth a try — add this line in the update_account_balance! method inside AccountEntry — here’s the whole method including the new line:

def update_account_balance!
  account.update_balance!
  account.save
end

It’s a long shot, but worth a try.

jitendra goyal March 9, 2016 12:34pm

jitendra goyal March 9, 2016 12:50pm

AccountEntry.count

(4.2ms) SELECT COUNT(*) FROM account_entries

=> 21

AccountEntry.find(1)

AccountEntry Load (0.4ms) SELECT account_entries.* FROM account_entries WHERE account_entries.id = 1 LIMIT 1

=> #TimeEntry id: 1, time: 1.0, customer_id: nil, employee_id: 1578, created_at: «2016-03-04 05:37:07», updated_at: «2016-03-04 05:59:26», account_id: 1, type: «TimeEntry», amount: 40, state: nil
i

jitendra goyal March 9, 2016 12:54pm

How to set the state of account_entries.id = 1 to ‘submitted’.

Steve Hunter March 9, 2016 12:57pm

Two things here; first your question, second some other thoughts …

To set the time entry, something like:

a = AccountEntry.find(1)
a.state = 'submitted'

If that throws an error it should be clear what’s wrong with the code. (It works!)

Should the Time Entries you load via the web page show up? They’re not doing in my version of your app.

Load you server and go to /employees visit one of their show pages like:

Load the console and type TimeEntry.count, then add a time entry on the page so ther should be another TimeEntry … type reload! into console then TimeEntry.count again. I get the same value returned — zero in my case. Do you get an incremented number?

Steve Hunter March 9, 2016 1:01pm

If the state is already ‘submitted’, it’ll error out as the object will return false, a member of nil::NilClass.

So, if that is the case, the use of update_attributes is causing the state setting to fail; returning false, not an object of account. Any subsequent call of an account method on false will throw the error you’re seeing. I think.

jitendra goyal March 9, 2016 1:03pm

jitendra goyal March 9, 2016 1:07pm

jitendra goyal March 9, 2016 1:20pm

When I typed -TimeEntry.all.each { |t| t.update_attributes(state: «initial») }

instead of «submitted», i changed the state to «initial».
Then Im not getting error.

Steve Hunter March 9, 2016 1:25pm

Tried a bit more in console.

First, I created an Account and an AccountEntry:

a = Account.create(name: "AnAccount")
b = AccountEntry.create(account_id: a.id)
b.update_account_balance!

That works … previously, that was failing due to the lack of association with the Account id. I’m trying to figure out why that was happening.

jitendra goyal March 9, 2016 1:29pm

Your Commands is working.

jitendra goyal March 9, 2016 1:41pm

Problem is that, When we set the state = «submitted», query is not executing.

jitendra goyal March 9, 2016 1:57pm

Sorry Steve for today to bother u.

jitendra goyal March 9, 2016 2:14pm

TimeEntry.all.each { |t| t.update_attributes(state: «initial») }

SyntaxError: (irb):9: syntax error, unexpected &
…t| t.update_attributes(state: «initial») }
… ^
(irb):9: syntax error, unexpected ‘)’, expecting ‘}’
…tes(state: «initial») }

jitendra goyal March 9, 2016 2:38pm

TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

This Command is not working

jitendra goyal March 9, 2016 2:40pm

sorry for late reply, I lost the internet connection.

jitendra goyal March 9, 2016 2:42pm

jitendra goyal March 9, 2016 2:49pm

TimeEntry.all.each { |t| t.update_attributes(state: «submitted») }

TimeEntry Load (0.6ms) SELECT account_entries.* FROM account_entries WHERE account_entries.type IN (‘TimeEntry’)
(0.2ms) BEGIN

Account Load (0.3ms) SELECT accounts.* FROM accounts WHERE accounts.id = 1 LIMIT 1
(0.3ms) ROLLBACK

NoMethodError: undefined method `update_balance!’ for nil:NilClass

from /Users/jitendragoyal/biller/app/models/account_entry.rb:24:in `update_account_balance!’

jitendra goyal March 9, 2016 2:55pm

take ur time,don’t worry.

Steve Hunter March 9, 2016 3:14pm

This is a pain, and there must be a way to do this in console but I can’t figure it out.

So, I’ve created a new view folder called time_entries and inside there I’ve created a view called index.html.erb. That file holds this code:

<% @time_entries.each do |te| %>
  <%= te.account_id %>
<% end %>

So that loops through all the time entries and outputs the account_id. BUT, @time_entries doesn’t exist. And nor does the index action. So, go to your time_entries_controller.rb and add:

def index
  @time_entries = TimeEntry.all
end

Now, we need a route else that’ll not work at all. So find your config/routes.rb file and add this:

get 'time_entries', to: 'time_entries#index'

You could probably just add resources :time_entries to the root of the file, rather than inside a do block — same difference.

So, what we’ve done there is created a loop in the view to iterate over all the time entries. In the controller, we’ve created an action for that type of view, the index action, and have created the @time_entries variable that’s available across all the MVC files. To get the page to work, we’ve added a route that sends all requests for /time_entries to the right view, using the correct controller.

I hope that made sense … in my browser, I have 4 numbers, one for each time entry, and no nil values. Have a go and see what you get, and I’ll refine this a little further, to see if I can get it to correct the issues you’re having.

jitendra goyal March 9, 2016 9:46pm

Hi Steve,sorry yesterday my internet was doing problem.
Stiil i m getting same error.

jitendra goyal March 9, 2016 10:14pm

yeah i tried, but still not working.

jitendra goyal March 9, 2016 10:17pm

I think we have different timings.means here is morning now and there?

jitendra goyal March 9, 2016 10:19pm

jitendra goyal March 9, 2016 10:22pm

Means same problem as last night.

jitendra goyal March 9, 2016 10:22pm

State = Submitted is not working

jitendra goyal March 9, 2016 10:23pm

Steve Hunter March 9, 2016 10:26pm

Yes. My code wasn’t there to fix the error; that exists within your database. It is there to identify what’s wrong with your database.

Have you implemented all the code changes in my post about time_entries?

jitendra goyal March 9, 2016 10:29pm

Yes I have implemented.But Nothing make difference…..what should i do?

jitendra goyal March 9, 2016 10:42pm

jitendra goyal March 10, 2016 9:01am

Hi Steve,
I tried to solve the issue.I think, the problem is between account_id and time_entries.I m sharing some screenshots to understand the issue—

jitendra goyal March 10, 2016 9:01am

This is the Customer list.

customer list

jitendra goyal March 10, 2016 9:08am

I have some time_entries for few customers.like i have time_entry for customer «Kessler Denesik and Mayer and Sons».When I clicked on the Customer link for «Kessler Denesik and Mayer and Sons» on http://localhost:3000/accounts page it give me error—

Accounts#show

jitendra goyal March 10, 2016 9:11am

It didn’t give me error for those customers for which i don’t have time entries.

jitendra goyal March 10, 2016 9:12am

Imgur

jitendra goyal March 10, 2016 9:14am

jitendra goyal March 10, 2016 9:17am

I don’t remember the command. I did follow the video.give me a minute.

jitendra goyal March 10, 2016 9:19am

I have already run your code but it doesn’t work.

jitendra goyal March 10, 2016 9:22am

Imgur

jitendra goyal March 10, 2016 9:23am

Imgur

jitendra goyal March 10, 2016 9:26am

Imgur

jitendra goyal March 10, 2016 9:29am

Imgur

jitendra goyal March 10, 2016 9:30am

You are talking about these two lines —

get ‘time_entries’,
to: ‘time_entries#index’

jitendra goyal March 10, 2016 9:33am

ok, i did it.it give me blank page—

Imgur

jitendra goyal March 10, 2016 9:38am

I reverted the code and result is-

Imgur

jitendra goyal March 10, 2016 9:39am

jitendra goyal March 10, 2016 9:41am

jitendra goyal March 10, 2016 12:39pm

Yeah you are right Steve.This is the longest thread in treehouse community.now what i should to do next..

jitendra goyal March 10, 2016 12:50pm

Thanks Steve for your help.but There is no project file regarding to biller.Hampton didn’t explain many things, so I didn’t learn too much.Thats why Im not good at ACTIVE RECORD BASICS.

jitendra goyal March 10, 2016 1:14pm

For some Download it says u need to upgrade to pro.i don’t have pro subscription.

jitendra goyal March 10, 2016 1:19pm

jitendra goyal March 20, 2016 2:40pm

jitendra goyal March 20, 2016 3:03pm

how r u?
I want to ask one question.

jitendra goyal March 20, 2016 3:05pm

how to create a rail instance for existing database?

jitendra goyal March 20, 2016 3:17pm

jitendra goyal April 3, 2016 3:29am

jitendra goyal April 3, 2016 10:28am

i do have access of company database through VPN but i dont know how to access the ruby code of that database.I can connect the my laptop to that server.

jitendra goyal April 3, 2016 10:47am

i have access of company database server , which i am accessing via mysql workbench.
now he gave me task , to perform task i need to access ruby code and i am so new ,
i don’t know if i can access rails using server database ?

is it possible to access rails instance when server access been given. ?

jitendra goyal April 3, 2016 10:48am

i am using tunnelblick to connect company DB.

Steve Hunter April 3, 2016 10:55am

Try running a console on the Rails instance. Navigate to the root of the server and run rails c — that should give you access to the instances and tables. Without knowing what you’re dealing with, I’m only going to be guessing here!

ActionView::Template::Error (undefined method. ) Works locally, but not on Heroku

I didn’t have trouble on previous code pushed to Heroku, but this last push has messed up. The only thing that has changed is instead of looping through each student , it’s now looping through each user .

Background

The code works locally, but not on Heroku. The page that is raising an error on Heroku is a list (index) of all the students. What the code is doing is looping through all Users that have a profile_type = «Student» .

For some reason it’s trying to access the polymorphic association (profile) on a Student object, when the User object should be used instead.

Log from Heroku

Application Code

student.rb

students_controller

index.html.erb for students

user.rb

What I have tried:

  • Double checked that all migrations from local/dev are in sync with Heroku
  • Cloned the Heroku files to double check that they are running the same codebase
  • Ran the heroku restart command
  • Double checked and ran heroku run rake db:migrate to make sure everything
  • Double checked the database to make sure all data and columns are the same
  • I’ve checked on other machines and browsers; still the same issue

Definitely frustrating. Thanks for any help!

2 Answers 2

Thanks to Leo Correa’s suggestion, I started the rails server in production mode and was able to reproduce the error. (I used the RAILS_ENV=production rails s to launch the server locally in production mode.)

I narrowed the issue down to config.eager_load . It was originally set to true , but changing it to config.eager_load = false fixed the issue.

Still not sure why the issue persisted in the first place, but it’s fixed now!

I had the same issue and setting config.eager_load to true fixed it. However this is not a recommended setting in production, so I tried to find out what was really the issue.

I finally realised that it was because of some other model class that was incorrectly set up (it was still under development), even though it had absolutely nothing to do with the erroring models. When the config.eager_load option is set to true it causes Rails to load all classes at startup for optimisation reasons. If some model classes are incorrect, then this causes things to be messed up and the relations may become weird.

As soon as I deleted the wrong/incomplete model class, everything started to work again.

Источник

ActionView is raising errors in the test environment after upgrading to Rails 6 (ActionView::Template::Error: undefined method `_app_views_xxxxx) #40613

Comments

yjukaku commented Nov 12, 2020 •

Expected behavior

ActionView template compilation is reliably executed in test and dev environments.

Actual behavior

Tests (and sometimes the dev server) fail intermittently with exceptions like

In our existing Rails app that we recently upgraded from 5.2.4 to 6.0.3.4, we’re consistently facing build failures with the described exception. Rerunning a few times will sometimes make the issue go away.

System configuration

Rails version:
Rails 6.0.3.4

Ruby version:
ruby 2.7.2p137

Unfortunately, I can’t figure out steps to reproduce this on a new app :(, but I have done some diving into the ActionView code to try to figure out what’s going on.

I’m running a file with controller tests, and when I run the tests with a particular seed, I’m able to consistently reproduce the error. Using pry-debugger and puts , I’ve worked out that ActionView template compilation seems to be the issue. For whatever reason, the ActionView::Template for the file has the @compiled flag set to true , but the method_name generated by the template has not been defined on the view .

I’ve found two things that seem to stop the error.

First is adding a line before the compile! call above:

For obvious reasons, this forces ActionView to (re)compile the template, and this prevents the error from being raised.

Second, I’ve found that slowing down our first call to render seems to stop the issue from happening. In the controller test I mentioned above, I’m testing FoosController#show . FoosController#show explicitly calls render «show» (for unrelated reasons). If I insert a sleep(0.1) call right before the render «show» line, the issue disappears. If I then change that sleep call to sleep(0.0) , the error returns. I don’t know what that means, but it seems like a race condition.

@jhawthorn , I know you were working on the template compilation recently. Do you have any ideas what could be happening here?

The text was updated successfully, but these errors were encountered:

jhawthorn commented Nov 12, 2020

Thanks for the detailed report. I appreciate the difficulty in making a simple reproduction.

This seems a lot like #37928, which should have been fixed in 6.0.2+, but this could be something similar.

It’s surprising to hear it fails in tests, where I would generally expect fewer concurrency issues.

yjukaku commented Nov 13, 2020 •

Thanks for that link. I didn’t find anything earlier when searching for similar errors.

I was able to confirm locally that it seems to be an issue with the cache expiry. Here’s what I did:

  1. Added instrumentation to our tests to puts ‘rendered template’ whenever «!render_template.action_view» was called.
  2. bundle open actionview to edit cache_expiry.rb with the following three changes:
  1. Ran the tests that were failing earlier.

Here’s what I found: As expected, after all of the views were rendered and a bunch of «rendered template» were output to the console, the text «Entered mutex» was output. RSpec displayed that the first test passed successfully.

However, the next part is strange. Before the «Left mutex» was displayed, there were a lot more «rendered template» lines output.

So it seems that the mutex for entering the code clear_cache_if_necessary is not preventing new templates from being compiled while it gets cleared. That makes sense — the mutex is not shared across the insertion into the cache and clearing of the cache.

I’m not sure why our team seems to be the only one on the interwebs facing this issue, though. We don’t have a particular huge app. Maybe something else in our codebase is making the clear_cache_if_necessary call slower than most apps.

Does my analysis make sense to you?

jhawthorn commented Nov 14, 2020

Thanks! There’s a few interesting things here, which might help explain why there aren’t more folks experiencing this and might help us find a reproduction outside of your app.

I’m guessing you have config.cache_classes = false but maybe not config.action_view.cache_template_loading = true in config/environments/test.rb ? I feel like in most cases we shouldn’t want/need to be checking view expiry from tests. (IMO it’s a bug that we get errors regardless of configuration, but this might help narrow down the needed conditions for this failure)

Is it possible #append_view_path is being used? That seems to be a common source of problems. (similarly, IMO a bug if it causes problems, but would narrow down the issue)

The thing I’d most like to know is where these renders are coming from (standard requests? a mailer? system tests?). It seems a bit odd that we’re getting a few rendered template from the first test without first going through the cache expiry, but then we do start running the cache expiry before that first test ends, but it continues running when when the test finishes, which is surprising. There’s clearly multiple threads so I’d like to know what they are.

yjukaku commented Nov 16, 2020

I’m guessing you have config.cache_classes = false but maybe not config.action_view.cache_template_loading = true in config/environments/test.rb? I feel like in most cases we shouldn’t want/need to be checking view expiry from tests.

We do have config.cache_classes = false in our test.rb , but we don’t have anything for config.action_view.cache_template_loading . However, according the Rails docs, that value should default to the same as config.cache_classes (false), and it does when I check the value of ActionView::Resolver.caching? during a test run.

On the other hand, setting it to true does seem to make the error go away.

Is it possible #append_view_path is being used? That seems to be a common source of problems. (similarly, IMO a bug if it causes problems, but would narrow down the issue)

I don’t see use of append_view_path (or prepend_view_path ) in our codebase.

The thing I’d most like to know is where these renders are coming from (standard requests? a mailer? system tests?)

These are coming from

Our application.html.slim renders a lot of partials, and at some point while rendering those partials, the error is raised.

It seems a bit odd that we’re getting a few rendered template from the first test without first going through the cache expiry, but then we do start running the cache expiry before that first test ends, but it continues running when when the test finishes, which is surprising. There’s clearly multiple threads so I’d like to know what they are.

Sorry, I don’t follow. 🤔 AFAIU, the cache expiry should happen after the request finishes, right? So it’s expected that we see templates rendered and then the cache expiry.

I agree it’s surprising that a new request can start while the cache is getting expired. That’s really strange and it would indicate that rspec is running the next test in a new thread, right? That would be really unexpected. We don’t have any special rspec config which could cause that to happen, AFAICT.

Источник

ActionView::Template::Error (undefined method `page_param’ for nil:NilClass)

ERROR

Steps taken: Installed redmine (everything ok) Installed easyredmine (everything ok) Installed Gitolite3 (everything ok) Installed Git_hosting_plugin 1.2.0 (ouch)

I followed the getting started guide for the plugin. My boss wants the PassengerUser to be redmine, so I set up redmine as the redmine user account. The redmine user can communicate with gitolite through SSH as described. I also set up the sudoers.d/redmine without any trouble.

Everything seems to work at first, and logging into localIP/redmine works, with Passenger configured for the redmine user.

My problem is that when i visit the redmine/users page it gives the error described above, written into the production.log. I have no idea why page_param is undefined, or what is going wrong with pagination_links_full. I do not want to modify the ruby file because of expected trouble when updating at some later point.

I’m new to installing redmine and the other programs on linux server environments, and have little experience with UNIX systems, though I would say my understanding grows a lot by the day.It could be a nooby mistake. It could be a bug. It could be a mismatch in versions, where version A of a method is used to call upon a later improved version of another piece of code. It could be that the info has to be taken from somewhere and the redmine installation is trying to get the information without the proper configuration.

If I had to guess, my best guess would be that the ruby pagination file is not compatible with the rest of the configuration and should likely be replaced by a different version.

Can someone please explain to me what is going wrong here, or how to fix this problem (or preferably both)?

Would really appreciate it.

UPDATE (18/02/2016): by editing the template the user page is accessible again.

However, this is a dirty temporary fix which would cause problems if the amount of users would be more than fit into one page. Who can help me find a permanent solution?

Thanks a lot for your feedback. Right now I am not assigned any extra time to resolve the issue but I did have a look based on what you wrote. By the way, any plugin starting with easy_ is a standard easyredmine plugin, so the plugin list is smaller than it appears to be.

The directories which have a users/index.html.erb file:

The top two are redmine and easyredmine, which worked fine before installing the redmine_git_hosting plugin. The bottom one seems to be a standard redmine_extensions gem.

If I had to make a more educated guess than before, I would say that combined with the fact that the problem did not occur with the other installations, the redmine_git_hosting plugin seems to be the culprit, or atleast cause problems combined with redmine and/or easyredmine. It was also in the redmine git hosting directory and file where I implemented the dirty fix by modifying the template file, which temporarily ‘fixed’ the problem. Funny how a simple piece of code to determine how many pages of users to display, which is essentially obsolete unless your redmine environment has more than one page full of users, can cause the entire user management interface to be disabled.

the Plugin does seem to patch the UsersController: /opt/redmine/redmine-3.1.3/plugins/redmine_git_hosting/lib/redmine_git_hosting/patches/users_controller_patch.rb

The template I modified was the one from the error log, so it was already constructed to use @user_pages. I did not find time yet to dig deeper into the users controller. Do you think modifying the Users Controller to set the variable, testing if it works that way, and then reporting the problem and proposed solution to the authors of the redmine_git_hosting plugin would be the best way to go about it?

Sidenote: You said both, but in this case, would it not be worth mentioning it to three parties? (redmine/easyredmine/redmine_git_hosting). How would one go about reporting something like this? Would it involve making a post on their forum or sending an email with information to the company? I can think of many ways to report it but am unfamiliar with such procedures and do not know if there is a standardized way to do it outside obvious possible ways to communicate. I also do not know if I should test it on redmine without easyredmine, before reporting it to redmine. If I were working for redmine I would appreciate any heads up about possible problems with plugins, so I could archive the potential problem and test if that also applies for redmine. From my boss’s perspective I do not think he is interested in assigning time he has to pay for to get to the bottom of it.

Thanks again for having someone’s brain to pick.

Источник

Skip to content



Open


Issue created Apr 02, 2020 by Sanad Liaquat@sliaquatMaintainer0 of 2 checklist items completed0/2 checklist items

`undefined method `persisted?’ for nil:NilClass` causing error 500 and transient failure in /qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb:6

Summary

Sentry: https://sentry.gitlab.net/gitlab/staginggitlabcom/issues/1498834

NoMethodError: undefined method `persisted?' for nil:NilClass
  from deploy_tokens_helper.rb:5:in `expand_deploy_tokens_section?'
  from /opt/gitlab/embedded/service/gitlab-rails/app/views/shared/deploy_tokens/_index.html.haml:1:in `_app_views_shared_deploy_tokens__index_html_haml__213050039714906385_70190111258600'
  from action_view/base.rb:274:in `_run'
  from action_view/template.rb:185:in `block in render'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/template.rb:386:in `instrument_render_template'
  from action_view/template.rb:183:in `render'
  from action_view/renderer/partial_renderer.rb:358:in `block in render_partial'
  from action_view/renderer/abstract_renderer.rb:89:in `block in instrument'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/renderer/abstract_renderer.rb:88:in `instrument'
  from action_view/renderer/partial_renderer.rb:347:in `render_partial'
  from action_view/renderer/partial_renderer.rb:317:in `render'
  from action_view/renderer/renderer.rb:65:in `render_partial_to_object'
  from action_view/renderer/renderer.rb:53:in `render_partial'
  from action_view/helpers/rendering_helper.rb:38:in `render'
  from /opt/gitlab/embedded/service/gitlab-rails/app/views/projects/settings/ci_cd/show.html.haml:55:in `_app_views_projects_settings_ci_cd_show_html_haml__2399158301310529608_70190012860500'

Expand for full stack trace

NoMethodError: undefined method `persisted?' for nil:NilClass
  from deploy_tokens_helper.rb:5:in `expand_deploy_tokens_section?'
  from /opt/gitlab/embedded/service/gitlab-rails/app/views/shared/deploy_tokens/_index.html.haml:1:in `_app_views_shared_deploy_tokens__index_html_haml__213050039714906385_70190111258600'
  from action_view/base.rb:274:in `_run'
  from action_view/template.rb:185:in `block in render'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/template.rb:386:in `instrument_render_template'
  from action_view/template.rb:183:in `render'
  from action_view/renderer/partial_renderer.rb:358:in `block in render_partial'
  from action_view/renderer/abstract_renderer.rb:89:in `block in instrument'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/renderer/abstract_renderer.rb:88:in `instrument'
  from action_view/renderer/partial_renderer.rb:347:in `render_partial'
  from action_view/renderer/partial_renderer.rb:317:in `render'
  from action_view/renderer/renderer.rb:65:in `render_partial_to_object'
  from action_view/renderer/renderer.rb:53:in `render_partial'
  from action_view/helpers/rendering_helper.rb:38:in `render'
  from /opt/gitlab/embedded/service/gitlab-rails/app/views/projects/settings/ci_cd/show.html.haml:55:in `_app_views_projects_settings_ci_cd_show_html_haml__2399158301310529608_70190012860500'
  from action_view/base.rb:274:in `_run'
  from action_view/template.rb:185:in `block in render'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/template.rb:386:in `instrument_render_template'
  from action_view/template.rb:183:in `render'
  from action_view/renderer/template_renderer.rb:59:in `block (2 levels) in render_template'
  from action_view/renderer/abstract_renderer.rb:89:in `block in instrument'
  from active_support/notifications.rb:180:in `block in instrument'
  from active_support/notifications/instrumenter.rb:24:in `instrument'
  from active_support/notifications.rb:180:in `instrument'
  from action_view/renderer/abstract_renderer.rb:88:in `instrument'
  from action_view/renderer/template_renderer.rb:58:in `block in render_template'
  from action_view/renderer/template_renderer.rb:66:in `render_with_layout'
  from action_view/renderer/template_renderer.rb:57:in `render_template'
  from action_view/renderer/template_renderer.rb:13:in `render'
  from action_view/renderer/renderer.rb:61:in `render_template_to_object'
  from action_view/renderer/renderer.rb:29:in `render_to_object'
  from action_view/renderer/renderer.rb:22:in `render'
  from action_view/helpers/rendering_helper.rb:34:in `block in render'
  from action_view/base.rb:304:in `in_rendering_context'
  from action_view/helpers/rendering_helper.rb:30:in `render'
  from ee/application_helper.rb:43:in `render_ce'
  from /opt/gitlab/embedded/service/gitlab-rails/ee/app/views/projects/settings/ci_cd/show.html.haml:1:in `_ee_app_views_projects_settings_ci_cd_show_html_haml__1858615745815790089_70190012471160'
  from action_view/base.rb:274:in `_run'
  from action_view/template.rb:185:in `block in render'
  from active_support/notifications.rb:182:in `instrument'
  from action_view/template.rb:386:in `instrument_render_template'
  from action_view/template.rb:183:in `render'
  from action_view/renderer/template_renderer.rb:59:in `block (2 levels) in render_template'
  from action_view/renderer/abstract_renderer.rb:89:in `block in instrument'
  from active_support/notifications.rb:180:in `block in instrument'
  from active_support/notifications/instrumenter.rb:24:in `instrument'
  from active_support/notifications.rb:180:in `instrument'
  from action_view/renderer/abstract_renderer.rb:88:in `instrument'
  from action_view/renderer/template_renderer.rb:58:in `block in render_template'
  from action_view/renderer/template_renderer.rb:66:in `render_with_layout'
  from action_view/renderer/template_renderer.rb:57:in `render_template'
  from action_view/renderer/template_renderer.rb:13:in `render'
  from action_view/renderer/renderer.rb:61:in `render_template_to_object'
  from action_view/renderer/renderer.rb:29:in `render_to_object'
  from action_view/rendering.rb:118:in `block in _render_template'
  from action_view/base.rb:304:in `in_rendering_context'
  from action_view/rendering.rb:117:in `_render_template'
  from action_controller/metal/streaming.rb:219:in `_render_template'
  from action_view/rendering.rb:103:in `render_to_body'
  from action_controller/metal/rendering.rb:52:in `render_to_body'
  from action_controller/metal/renderers.rb:142:in `render_to_body'
  from abstract_controller/rendering.rb:25:in `render'
  from action_controller/metal/rendering.rb:36:in `render'
  from action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
  from active_support/core_ext/benchmark.rb:14:in `block in ms'
  from benchmark.rb:308:in `realtime'
  from active_support/core_ext/benchmark.rb:14:in `ms'
  from action_controller/metal/instrumentation.rb:44:in `block in render'
  from action_controller/metal/instrumentation.rb:85:in `cleanup_view_runtime'
  from active_record/railties/controller_runtime.rb:34:in `cleanup_view_runtime'
  from elasticsearch/rails/instrumentation/controller_runtime.rb:20:in `cleanup_view_runtime'
  from action_controller/metal/instrumentation.rb:43:in `render'
  from application_controller.rb:125:in `render'
  from projects/settings/ci_cd_controller.rb:71:in `block (2 levels) in create_deploy_token'
  from action_controller/metal/mime_responds.rb:214:in `respond_to'
  from projects/settings/ci_cd_controller.rb:67:in `create_deploy_token'
  from action_controller/metal/basic_implicit_render.rb:6:in `send_action'
  from abstract_controller/base.rb:196:in `process_action'
  from action_controller/metal/rendering.rb:30:in `process_action'
  from abstract_controller/callbacks.rb:42:in `block in process_action'
  from active_support/callbacks.rb:112:in `block in run_callbacks'
  from gitlab/ip_address_state.rb:10:in `with'
  from ee/application_controller.rb:43:in `set_current_ip_address'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from gitlab/auth/current_user_mode.rb:56:in `with_current_admin'
  from application_controller.rb:482:in `set_current_admin'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from gitlab/session.rb:11:in `with_session'
  from application_controller.rb:470:in `set_session_storage'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from gitlab/i18n.rb:55:in `with_locale'
  from gitlab/i18n.rb:61:in `with_user_locale'
  from application_controller.rb:464:in `set_locale'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from gitlab/error_tracking.rb:34:in `with_context'
  from application_controller.rb:555:in `sentry_context'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from raven/integrations/rails/controller_transaction.rb:7:in `block in included'
  from active_support/callbacks.rb:121:in `instance_exec'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from marginalia.rb:111:in `record_query_comment'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from gitlab/application_context.rb:48:in `block in use'
  from labkit/context.rb:32:in `with_context'
  from gitlab/application_context.rb:48:in `use'
  from gitlab/application_context.rb:20:in `with_context'
  from application_controller.rb:455:in `set_current_context'
  from active_support/callbacks.rb:121:in `block in run_callbacks'
  from active_support/callbacks.rb:139:in `run_callbacks'
  from abstract_controller/callbacks.rb:41:in `process_action'
  from action_controller/metal/rescue.rb:22:in `process_action'
  from action_controller/metal/instrumentation.rb:33:in `block in process_action'
  from active_support/notifications.rb:180:in `block in instrument'
  from active_support/notifications/instrumenter.rb:24:in `instrument'
  from active_support/notifications.rb:180:in `instrument'
  from action_controller/metal/instrumentation.rb:32:in `process_action'
  from action_controller/metal/params_wrapper.rb:245:in `process_action'
  from active_record/railties/controller_runtime.rb:27:in `process_action'
  from abstract_controller/base.rb:136:in `process'
  from action_view/rendering.rb:39:in `process'
  from action_controller/metal.rb:191:in `dispatch'
  from action_controller/metal.rb:252:in `dispatch'
  from action_dispatch/routing/route_set.rb:51:in `dispatch'
  from action_dispatch/routing/route_set.rb:33:in `serve'
  from action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
  from action_dispatch/routing/mapper.rb:48:in `serve'
  from action_dispatch/journey/router.rb:49:in `block in serve'
  from action_dispatch/journey/router.rb:32:in `each'
  from action_dispatch/journey/router.rb:32:in `serve'
  from action_dispatch/routing/route_set.rb:837:in `call'
  from omniauth/strategy.rb:192:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from omniauth/strategy.rb:420:in `call_app!'
  from omni_auth/strategies/group_saml.rb:41:in `other_phase'
  from omniauth/strategy.rb:190:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from omniauth/strategy.rb:192:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from omniauth/strategy.rb:192:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from omniauth/strategy.rb:192:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from omniauth/strategy.rb:192:in `call!'
  from omniauth/strategy.rb:169:in `call'
  from gitlab/middleware/rails_queue_duration.rb:27:in `call'
  from gitlab/metrics/rack_middleware.rb:17:in `block in call'
  from gitlab/metrics/transaction.rb:62:in `run'
  from gitlab/metrics/rack_middleware.rb:17:in `call'
  from gitlab/request_profiler/middleware.rb:17:in `call'
  from gitlab/database/load_balancing/rack_middleware.rb:39:in `call'
  from labkit/middleware/rack.rb:19:in `block in call'
  from labkit/context.rb:32:in `with_context'
  from labkit/middleware/rack.rb:18:in `call'
  from gitlab/jira/middleware.rb:19:in `call'
  from gitlab/middleware/go.rb:20:in `call'
  from gitlab/etag_caching/middleware.rb:13:in `call'
  from batch_loader/middleware.rb:11:in `call'
  from apollo_upload_server/middleware.rb:20:in `call'
  from gitlab/middleware/multipart.rb:121:in `call'
  from rack/attack.rb:169:in `call'
  from warden/manager.rb:36:in `block in call'
  from warden/manager.rb:34:in `catch'
  from warden/manager.rb:34:in `call'
  from rack/cors.rb:98:in `call'
  from rack/tempfile_reaper.rb:15:in `call'
  from rack/etag.rb:25:in `call'
  from rack/conditional_get.rb:38:in `call'
  from rack/head.rb:12:in `call'
  from action_dispatch/http/content_security_policy.rb:18:in `call'
  from gitlab/middleware/read_only/controller.rb:53:in `call'
  from gitlab/middleware/read_only.rb:18:in `call'
  from rack/session/abstract/id.rb:232:in `context'
  from rack/session/abstract/id.rb:226:in `call'
  from action_dispatch/middleware/cookies.rb:648:in `call'
  from gitlab/middleware/same_site_cookies.rb:27:in `call'
  from action_dispatch/middleware/callbacks.rb:27:in `block in call'
  from active_support/callbacks.rb:101:in `run_callbacks'
  from action_dispatch/middleware/callbacks.rb:26:in `call'
  from action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
  from action_dispatch/middleware/debug_exceptions.rb:32:in `call'
  from action_dispatch/middleware/show_exceptions.rb:33:in `call'
  from gitlab/middleware/basic_health_check.rb:25:in `call'
  from rails/rack/logger.rb:38:in `call_app'
  from rails/rack/logger.rb:26:in `block in call'
  from active_support/tagged_logging.rb:80:in `block in tagged'
  from active_support/tagged_logging.rb:28:in `tagged'
  from active_support/tagged_logging.rb:80:in `tagged'
  from rails/rack/logger.rb:26:in `call'
  from action_dispatch/middleware/remote_ip.rb:81:in `call'
  from gitlab/middleware/request_context.rb:23:in `call'
  from request_store/middleware.rb:9:in `call'
  from action_dispatch/middleware/request_id.rb:27:in `call'
  from rack/method_override.rb:22:in `call'
  from rack/runtime.rb:22:in `call'
  from rack/timeout/core.rb:123:in `block in call'
  from rack/timeout/support/timeout.rb:19:in `timeout'
  from rack/timeout/core.rb:122:in `call'
  from /opt/gitlab/embedded/service/gitlab-rails/config/initializers/fix_local_cache_middleware.rb:9:in `call'
  from action_dispatch/middleware/executor.rb:14:in `call'
  from rack/sendfile.rb:111:in `call'
  from gitlab/metrics/requests_rack_middleware.rb:49:in `call'
  from action_dispatch/middleware/host_authorization.rb:77:in `call'
  from raven/integrations/rack.rb:51:in `call'
  from rails/engine.rb:526:in `call'
  from rails/railtie.rb:190:in `public_send'
  from rails/railtie.rb:190:in `method_missing'
  from gitlab/middleware/release_env.rb:12:in `call'
  from rack/urlmap.rb:68:in `block in call'
  from rack/urlmap.rb:53:in `each'
  from rack/urlmap.rb:53:in `call'
  from puma/configuration.rb:228:in `call'
  from puma/server.rb:691:in `handle_request'
  from puma/server.rb:481:in `process_client'
  from puma/server.rb:335:in `block in run'
  from puma/thread_pool.rb:138:in `block in spawn_thread'

This bug is causing E2E tests to intermittently fail (see below).

I was able to reproduce on GDK

Steps to reproduce

  1. Add a deploy token without selecting the read_repository scope

What is the current bug behavior?

Error 500 due to NoMethodError: undefined method persisted?’ for nil:NilClass`

What is the expected correct behavior?

read_repository is now the only available scope, so I would expect it to be enabled by default.

Or read_registry should be available as it is currently on GitLab.com and the user should be prompted to select one of the options if they try to create a token without selecting either.

Test failure details

Jobs:
Master: https://gitlab.com/gitlab-org/gitlab-qa-mirror/-/jobs/495698792
MR: https://gitlab.com/gitlab-org/gitlab-qa-mirror/-/jobs/495817004

Stack trace

Selenium::WebDriver::Error::StaleElementReferenceError:
        stale element reference: element is not attached to the page document
          (Session info: headless chrome=80.0.3987.162)
      # #0 0x558c8c0f8d29 <unknown>
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/response.rb:72:in `assert_ok'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/http/common.rb:88:in `new'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/http/common.rb:88:in `create_response'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/http/default.rb:114:in `request'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/http/common.rb:64:in `call'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/bridge.rb:167:in `execute'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/w3c/bridge.rb:567:in `execute'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/remote/w3c/bridge.rb:556:in `find_elements_by'
      # /usr/local/bundle/gems/selenium-webdriver-3.142.6/lib/selenium/webdriver/common/search_context.rb:80:in `find_elements'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/selenium/extensions/find.rb:17:in `find_by'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/selenium/extensions/find.rb:11:in `find_css'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/base.rb:107:in `find_css'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/queries/selector_query.rb:234:in `find_nodes_by_selector_format'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/queries/selector_query.rb:150:in `block in resolve_for'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/base.rb:77:in `synchronize'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/queries/selector_query.rb:149:in `resolve_for'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/finders.rb:289:in `block in synced_resolve'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/base.rb:83:in `synchronize'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/finders.rb:287:in `synced_resolve'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/node/finders.rb:52:in `find'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/session.rb:749:in `block (2 levels) in <class:Session>'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
      # ./qa/page/base.rb:84:in `find_element'
      # ./qa/support/page/logging.rb:38:in `find_element'
      # ./qa/page/base.rb:103:in `block in check_element'
      # ./qa/page/base.rb:37:in `block in retry_until'
      # ./qa/support/retrier.rb:56:in `block in retry_until'
      # ./qa/support/repeater.rb:21:in `repeat_until'
      # ./qa/support/retrier.rb:48:in `retry_until'
      # ./qa/page/base.rb:36:in `retry_until'
      # ./qa/page/base.rb:102:in `check_element'
      # ./qa/support/page/logging.rb:58:in `check_element'
      # ./qa/page/project/settings/deploy_tokens.rb:31:in `fill_scopes'
      # ./qa/resource/deploy_token.rb:40:in `block (2 levels) in fabricate!'
      # ./qa/scenario/actable.rb:16:in `perform'
      # ./qa/page/project/settings/ci_cd.rb:26:in `block in expand_deploy_tokens'
      # ./qa/page/settings/common.rb:20:in `block in expand_section'
      # ./qa/page/base.rb:234:in `block in within_element'
      # /usr/local/bundle/gems/capybara-3.29.0/lib/capybara/session.rb:343:in `within'
      # ./qa/page/base.rb:233:in `within_element'
      # ./qa/support/page/logging.rb:143:in `within_element'
      # ./qa/page/settings/common.rb:11:in `expand_section'
      # ./qa/page/project/settings/ci_cd.rb:25:in `expand_deploy_tokens'
      # ./qa/resource/deploy_token.rb:37:in `block in fabricate!'
      # ./qa/scenario/actable.rb:16:in `perform'
      # ./qa/resource/deploy_token.rb:36:in `fabricate!'
      # ./qa/resource/base.rb:30:in `block (2 levels) in fabricate_via_browser_ui!'
      # ./qa/resource/base.rb:135:in `log_fabrication'
      # ./qa/resource/base.rb:30:in `block in fabricate_via_browser_ui!'
      # ./qa/resource/base.rb:118:in `do_fabricate!'
      # ./qa/resource/base.rb:29:in `fabricate_via_browser_ui!'
      # ./qa/specs/features/browser_ui/6_release/deploy_token/add_deploy_token_spec.rb:12:in `block (3 levels) in <module:QA>'

Screenshot / HTML page

release_deploy_token_creation_user_adds_a_deploy_token.html

Expand for screenshot

release_deploy_token_creation_user_adds_a_deploy_token

Container logs (production.log) show:

Started POST "/relative/gitlab-qa-sandbox-group/qa-test-2020-04-06-02-13-21-76de0541521cbc9f/project-to-deploy-062bff50ec852d92/-/settings/repository/deploy_token/create" for 172.19.0.3 at 2020-04-06 02:18:36 +0000
Processing by Projects::Settings::CiCdController#create_deploy_token as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "deploy_token"=>"[FILTERED]", "namespace_id"=>"gitlab-qa-sandbox-group/qa-test-2020-04-06-02-13-21-76de0541521cbc9f", "project_id"=>"project-to-deploy-062bff50ec852d92"}
Completed 500 Internal Server Error in 219ms (ActiveRecord: 58.7ms | Elasticsearch: 0.0ms | Allocations: 48580)
  
ActionView::Template::Error (undefined method `persisted?' for nil:NilClass):
    1: - expanded = expand_deploy_tokens_section?(@new_deploy_token)
    2: 
    3: %section.qa-deploy-tokens-settings.settings.no-animate#js-deploy-tokens{ class: ('expanded' if expanded), data: { qa_selector: 'deploy_tokens_settings' } }
    4:   .settings-header
  
app/helpers/deploy_tokens_helper.rb:5:in `expand_deploy_tokens_section?'
app/views/shared/deploy_tokens/_index.html.haml:1
app/views/projects/settings/ci_cd/show.html.haml:55
ee/app/helpers/ee/application_helper.rb:43:in `render_ce'
ee/app/views/projects/settings/ci_cd/show.html.haml:1
app/controllers/application_controller.rb:125:in `render'
app/controllers/projects/settings/ci_cd_controller.rb:71:in `block (2 levels) in create_deploy_token'
app/controllers/projects/settings/ci_cd_controller.rb:67:in `create_deploy_token'
ee/lib/gitlab/ip_address_state.rb:10:in `with'
ee/app/controllers/ee/application_controller.rb:43:in `set_current_ip_address'
app/controllers/application_controller.rb:479:in `set_current_admin'
lib/gitlab/session.rb:11:in `with_session'
app/controllers/application_controller.rb:470:in `set_session_storage'
lib/gitlab/i18n.rb:55:in `with_locale'
lib/gitlab/i18n.rb:61:in `with_user_locale'
app/controllers/application_controller.rb:464:in `set_locale'
lib/gitlab/error_tracking.rb:34:in `with_context'
app/controllers/application_controller.rb:555:in `sentry_context'
lib/gitlab/application_context.rb:48:in `block in use'
lib/gitlab/application_context.rb:48:in `use'
lib/gitlab/application_context.rb:20:in `with_context'
app/controllers/application_controller.rb:455:in `set_current_context'
lib/gitlab/middleware/rails_queue_duration.rb:27:in `call'
lib/gitlab/metrics/rack_middleware.rb:17:in `block in call'
lib/gitlab/metrics/transaction.rb:62:in `run'
lib/gitlab/metrics/rack_middleware.rb:17:in `call'
lib/gitlab/request_profiler/middleware.rb:17:in `call'
ee/lib/gitlab/jira/middleware.rb:19:in `call'
lib/gitlab/middleware/go.rb:20:in `call'
lib/gitlab/etag_caching/middleware.rb:13:in `call'
lib/gitlab/middleware/multipart.rb:121:in `call'
lib/gitlab/middleware/read_only/controller.rb:53:in `call'
lib/gitlab/middleware/read_only.rb:18:in `call'
lib/gitlab/middleware/same_site_cookies.rb:27:in `call'
lib/gitlab/middleware/basic_health_check.rb:25:in `call'
lib/gitlab/middleware/request_context.rb:23:in `call'
config/initializers/fix_local_cache_middleware.rb:9:in `call'
lib/gitlab/metrics/requests_rack_middleware.rb:49:in `call'
lib/gitlab/middleware/release_env.rb:12:in `call'

Tasks:

  • Fix the bug
  • Quality update the test so that it always specifies the scope(s) as expected

Edited Apr 06, 2020 by Mark Lapierre

I do have below layout which I use to build PDF.

doctype html
html
  head
    -# stylesheet_link_tag 'reports', media: 'all'
    base href="#{root_url}" target="_blank"
  body
    .container-fluid
      .row
        .col-xs-12
          = yield

Now when I am getting below error when I am trying to render it.

NoMethodError - undefined method `host' for nil:NilClass:
  actionpack (4.2.8) lib/action_controller/metal/url_for.rb:27:in `url_options'
  actionview (4.2.8) lib/action_view/routing_url_for.rb:121:in `url_options'
  actionpack (4.2.8) lib/action_dispatch/routing/route_set.rb:219:in `call'
  actionpack (4.2.8) lib/action_dispatch/routing/route_set.rb:345:in `block (2 levels) in define_url_helper'
  app/views/layouts/print.html.slim:5:in `_app_views_layouts_print_html_slim___2862807542511992517_70215288911320'

I reproduced it from Rails console too.

[1] pry(main)> ReportsController.new.render_to_string(action: 'sgs', layout: 'print', formats: [ :html ])
  Rendered reports/sgs.html.slim within layouts/print (108.5ms)
ActionView::Template::Error: undefined method `host' for nil:NilClass
from /Users/arup/.rvm/gems/ruby-2.3.3@DockingTestApp/gems/actionpack-4.2.8/lib/action_controller/metal/url_for.rb:27:in `url_options'

Any help to fix this which will work both production and development environment?

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Acronis unable to lock the disk boot your computer from a linux based как исправить
  • Acronis true image ошибка при клонировании диска
  • Acronis true image error 590330
  • Acronis true image error 0x1480006
  • Acronis loader fatal error boot drive partition not found что делать

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии