.includes followed by .where gets missing FROM-clause error

Accessing a PostgreSQL 9.4.4 database, I have code like:

previous_rsvps = Rsvp .select(‘rsvp.user_id’, ‘event_sessions.name’) .where(user_id: selected_attendees).includes(:rsvp_sessions).includes(:event_sessions) .where(“event_sessions.event_id IS NOT NULL”) .where(“event_sessions.name ~* ? OR event_sessions.name !~* ?”, “Workshop”, “Installfest”)

I believe this retrieves the expected records, because if I follow it with a command: previous_rsvps.pluck(‘event_sessions.name’).uniq.sort then the correct names are listed.

However, if I give the command: previous_rsvps.count then I get the error message: ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table “rsvp”.

Of course, I’m looking to do more with the previous_rsvps object, but this example captures the error. What causes this error and how do I get around it?

Unless you've done something to explicitly change it, the table name for a model will be plural. So instead of `rsvp.user_id`, you may need `rsvps.user_id`.

In fact you don't need rsvp at all here .select('user_id', 'event_sessions.name')

As always in this sort of situation with a complex statement that is not working as intended, a useful technique is to build the statement up a bit at a time, so start with previous_rsvps = Rsvp.select('user_id', 'event_sessions.name') and make sure previous_rsvps.count does not fail, then try previous_rsvps = Rsvp.select('user_id', 'event_sessions.name').where(user_id: selected_attendees) and so on till it fails. That may well give you a clue.

Colin

In fact you don't need rsvp at all here .select('user_id', 'event_sessions.name')

Can we know that? If the `event_sessions` table also has a `user_id` column, then wouldn't it be necessary to be explicit?

Ryan Bell wrote in post #1183301:

In fact you don't need rsvp at all here .select('user_id', 'event_sessions.name')

Can we know that? If the `event_sessions` table also has a `user_id` column, then wouldn't it be necessary to be explicit?

Ah, it looks like the #select method will assert the the correct table name(?). Cool. I'm always explicit when I do that, because I expected #select to behave the same as #order.

Good to know! Thanks.

I would be astonished if it did not default to the primary table. In fact now I look again I see that the OP has put includes(:event_sessions) after the select method rather than before, which I would have thought is wrong.

Colin

In fact now I look again I see that the OP has put includes(:event_sessions) after the select method rather than before, which I would have thought is wrong.

I don't think that matters as long as you are not passing a block to #select because of how active record composes scopes.

You could well be right.

Colin

Hi shauna,

Try changing the following part.

.includes(:rsvp_sessions).includes(:event_sessions)

to

.includes([:rsvp_sessions, :event_sessions])

I think you are getting the error because the second call of “includes” overridden the first one.

Thanks,

Genta

I think you are getting the error because the second call of "includes" overridden the first one.

I don't think that's the case.

Includes compose, rather than override. There should be no difference between calling

  .includes(:rsvp_sessions).includes(:event_sessions)

and calling

.includes([:rsvp_sessions, :event_sessions])