searching model and has_one association

Howdy.

I have these models:

User, field “mundane_name”

user has_one :instructor_profile (may or may not exist)

instructor_profile, field “sca_name”

belongs_to :user

I would like to craft a search on these fields, which is effectively this, but in one go:

matching_users = User.where(“mundane_name ILIKE ?”, “%#{target}%”)

matching_profiles = InstructorProfile.where(“sca_name ILIKE ?”, “%#{target}%”).map(&:user)

(matching_users + matching_profiles).uniq

However, I’m having problems formulating the query. Not all users have a profile, so some of the joins techniques would not work as they would only search a user if a profile existed as well.

Any suggestions?

Stupid question of the evening: Do users that don't have profiles have
sca_names?

They might, but I don’t care. :slight_smile:

For instructors, they are required. For others, not required since we never present them in print (yea, print) or bits. Also, the instructor_profile sca_name is really more of a “how do you want to be listed in the class listing we publish?” more so than “what’s your SCA name?”

–Michael

Howdy.

I have these models:

User, field "mundane_name"
user has_one :instructor_profile (may or may not exist)

instructor_profile, field "sca_name"
belongs_to :user

Are you sure you want separate models for these? I am always
suspicious when I see has_one. Often it is much easier just to
combine the tables into one and leave irrelevant fields empty. If
"instructor" is a role that certain players have then it might also be
worth looking at the cancan gem.

Colin

I admit I’m finding has_one to be a pain overall, since I end up having to check if it exists before pulling fields from it. Perhaps the simple, direct solution is just to move all these fields onto the user model, and add a flag to indicate if the user is an instructor, which guarantees those fields have been properly populated, and is quite easy to validate in the model.

Thanks for telling me something that I had considered before, but fought against for some silly reason, is likely the right answer. :slight_smile: