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

Models based on PostgreSQL views report 'nil' attribute #16555

Closed
tmikoss opened this issue Aug 19, 2014 · 5 comments
Closed

Models based on PostgreSQL views report 'nil' attribute #16555

tmikoss opened this issue Aug 19, 2014 · 5 comments

Comments

@tmikoss
Copy link
Contributor

tmikoss commented Aug 19, 2014

When trying to serialize a ActiveRecord model based on a PostgreSQL view rather than a table, I got a TypeError (nil is not a symbol) exception.

The cause seems to be ActiveRecord reporting additional nil attribute for the model. For example, given a view

CREATE OR REPLACE VIEW example_views AS
SELECT 1 AS id, text 'example' AS name

I get this

irb(main):001:0> ExampleView.first
=> #<ExampleView id: 1, name: "example">
irb(main):002:0> ExampleView.first.attributes
=> {"id"=>1, "name"=>"example", nil=>nil}
irb(main):003:0> ExampleView.column_names
=> ["id", "name"]
irb(main):004:0> ExampleView.first.attribute_names
=> ["id", "name", nil]

Bug observed with Rails 4.1.4 / 4.1.5, PostgreSQL 9.3.5. I've created a minimal Rails application with failing test cases at https://github.com/tmikoss/nil-attribute-in-views

@tmikoss tmikoss changed the title Models based on PostgreSQL views report 'nil' column Models based on PostgreSQL views report 'nil' attribute Aug 19, 2014
@senny
Copy link
Member

senny commented Aug 19, 2014

I can confirm the issue on 4.1.x. It's fixed on master (4.2.x).

Used this reproduction

@senny
Copy link
Member

senny commented Aug 19, 2014

Upon further investigation I found the cause of this behavior. It's because the model was not able to detect it's primary key. This leads to the nil => nil assignment on this line. Introduced by 522c0fd

You can circumvent the problem by doing:

class ExampleView < ActiveRecord::Base
  self.primary_key = "id"
end

Given that there is an easy workaround and the issue being fixed on master I tend to keep the behavior of 4-1-stable as is.

/cc @rafaelfranca

@tmikoss
Copy link
Contributor Author

tmikoss commented Aug 19, 2014

I actually encountered this problem in a view without primary key - it was providing 'flattened' representation of another table:

      CREATE OR REPLACE VIEW item_materials_unnest AS
      SELECT id AS item_id,
             unnest(akeys(manufacturing_materials))::int AS material_id,
             unnest(avals(manufacturing_materials))::int AS material_count
        FROM items

Given item with id: 1, manufacturing_materials: { 2 => 3, 4 => 5 } it would return two rows: item_id: 1, material_id: 2, material_count: 3 and item_id: 1, material_id: 4, material_count: 5.

My workaround was adding

  def attribute_names
    super.compact
  end

to the model. Given that a workaround exists, I'm okay with waiting for next release.

@senny senny closed this as completed in ec6eee5 Sep 9, 2014
@senny
Copy link
Member

senny commented Sep 9, 2014

@tmikoss I've added test-cases to ensure this will keep working in future versions. Thank you for reporting.

@tmikoss
Copy link
Contributor Author

tmikoss commented Sep 9, 2014

Thanks!

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

No branches or pull requests

2 participants