Dr.Gonzo
Dr.Gonzo

Reputation: 107

Joins queries in Ruby on Rails

Hi I am trying to run a joins query in rails. I am trying to output specific data from my User model while also getting data from my contactDetails model.. Code:

User.where(user_type: :lender).all.each do |user|
      result <<
          "#{user.id}, " +
          "#{user.contact_details},"
    end

The above prints out fine but when I add:

User.where(user_type: :lender).all.each do |user|
      result <<
          "#{user.id}, " +
          "#{user.contact_details}," +
          "#{user.contact_details.city}," +
          "#{user.contact_details.region}, " 
    end

Cannot find region or city.

Upvotes: 0

Views: 68

Answers (2)

Dr.Gonzo
Dr.Gonzo

Reputation: 107

I have solved this using present? method and then placing Ternary operators inside the code to a none applicable message for users who have not provided contact details. There was no need to add includes or joins:

User.where(user_type: :lender).all.each do |user|

      result <<
          "#{user.id}, " +
          "#{user.contact_details.present? ? user.contact_details.country : ' N/A '}," +
          "#{user.contact_details.present? ? user.contact_details.region : ' N/A ' }," +
          "#{user.contact_details.present? ? user.contact_details.city : ' N/A '}"
    end 

Upvotes: 0

SRack
SRack

Reputation: 12203

I think what's happening is user.contact_details is returning nil.

That would allow the first interpolation to work, as "#{nil}" just returns an empty string.

However, in the second example, when you call user.contact_details.city and user.contact_details.region, you're calling the methods city and region on nil, hence the error.

You can account for this using the safe operator to return empty strings, i.e.

user.contact_details&.city
# or in older Ruby versions
user.contact_details.try(:city)

Whether you want to have empty strings returned when the association exists is up to you, however, if you don't want them adding you could do something like:

result_string = user.id.to_s

if user.contact_details.present?
  result_string += "#{user.contact_details}," +
                   "#{user.contact_details.city}," +
                   "#{user.contact_details.region}, "
end

result << result_string

Finally, if you're expecting contact_details to be present, the problem likely lies in their creation and attachment to the user model - if that's the case, I'd suggest having a look at how you're doing this, and opening a new question with the relevant info if you can't get it to work.

Hope that helps - let me know if you've any questions on this at all.

Upvotes: 1

Related Questions