Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering cursor as collection in RoR give error undefined method 'size' for #<PostgreSQLCursor::Cursor #65

Closed
ukolovda opened this issue Mar 4, 2024 · 1 comment · Fixed by #66

Comments

@ukolovda
Copy link
Contributor

ukolovda commented Mar 4, 2024

Hello!

I try render a collection from cursor in Ruby on Rails (it may be useful for rendering big collections).
But got an error
undefined method 'size' for #<PostgreSQLCursor::Cursor:0x00007fcc4edd4dd0

Steps to reproduce:

Create user and database:

$ psql

postgres=# create user books with password 'books';
CREATE ROLE

postgres=# create database books_development owner books;
CREATE DATABASE

Create test application:

rails new books --database postgresql
cd books

Fix development block in config/database.yml file for connect to database.

Add controller and run server:

bundle add postgresql_cursor
rails g scaffold book name:string
rails db:migrate
rails s

Testing

Open in a browser: http://localhost:3000/books
It should show book list (now empty).

Append one or several books to list.

Modify view file for use render of collection

# app/views/books/index.html.erb
<p style="color: green"><%= notice %></p>

<h1>Books</h1>

<div id="books">
<%= render partial: "books/book", collection: @books %>
</div>

<%= link_to "New book", new_book_path %>

Link http://localhost:3000/books should show book list.

Modify view index.html.erb for use postgresql_cursor enum

Append .each_instance to books collection:

<%= render partial: "books/book", collection: @books.each_instance %>

Refresh book list in browser. It show an error:

NoMethodError in Books#index

Showing books/app/views/books/index.html.erb where line #6 raised:

undefined method `size' for #<PostgreSQLCursor::Cursor:0x00007fcc4edd4dd0 @sql="SELECT \"books\".* FROM \"books\"",  ...
@ukolovda
Copy link
Contributor Author

ukolovda commented Mar 4, 2024

Errors arises in 2 places:

https://github.com/rails/rails/blob/db30dd6fe71341ac132bb1e850bd4df2596a2803/actionview/lib/action_view/renderer/collection_renderer.rb#L159

https://github.com/rails/rails/blob/db30dd6fe71341ac132bb1e850bd4df2596a2803/actionview/lib/action_view/renderer/collection_renderer.rb#L186

(Rails, last version 7.1.3.2).

It can be fixed appending to cursor singleton method size returning Float::NAN:

# app/controllers/books_controller.rb
  ...
  def index
    @books = Book.all.each_instance
    @books.define_singleton_method(:size) { Float::NAN }
  end

And removing #each_instance call in a app/views/books/index.html.erb.

Rendering works fine.

Additional effect:

  • Logging row become:
Rendered collection of books/_book.html.erb [NaN times] (Duration: 24.5ms | Allocations: 11082)
  • Method last? in partial rendering always false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant