Search backwards in an one-to-many association

I am going to implement a small and simple search feature in my project.
But got a question about the scenario I have right now. So hope to get
some
tips from here.

First of all, this is a rails app.

There are two models, A and C.

A has_many C.

That’s to say, it might have some situation like this:

A1 related to C1, C2, C3, C4
A2 related to C2, C3, C4, C5
A3 related to C2, C3, C4, C8
A4 related to C3, C4, C8, C9
A5 related to C4, C8, C9, C20

Use C2, C3, C4 as keyword, I can get A1, A2, A3
Use C4, C8, C9 as keyword, I can get A4, A5

I consider that this can be done by using something straightforward like
A.Cs.includes?(C2,C3,C4).

But that requires an iteration of A. And I concern that it would have
some
performance issue.

Any advice or idea about this requirement ?

Thank you all, guys.

On 13 January 2016 at 07:22, Lei Z. [email protected] wrote:

That’s to say, it might have some situation like this:

A1 related to C1, C2, C3, C4
A2 related to C2, C3, C4, C5
A3 related to C2, C3, C4, C8
A4 related to C3, C4, C8, C9
A5 related to C4, C8, C9, C20

For that you need A has_and_belongs_many C, or (my preferred solution)
introduce a join model/table and use has_many through. You can’t use
has_many as that would require
C belongs_to A
which is not correct.

Any advice or idea about this requirement ?
I don’t understand exactly what your requirement is. in particular
what do you mean by “use C2, C3, C4 as keyword”, when each of the Cs
is a record in the db.
If you are trying to get all the As related to records C2, C3 and C4
then that is something like
(c2.as + c3.as +c4.as).uniq
though that may not be the most efficient way.

Colin

My mistake not making it clear enough.

Actually they have some attributes.

Let’s say,

A has a simple attribute called A.name and C also has a attribute
C.name.

Then A has_many C, which means C.a_id exists.

In my case, my requirement is that if users enter C2.name、 C3.name and
C4.name, I should show them A1.name or whatever attributes A might have
that needs to be displayed.

Anyway, thanks for your reply.

On 13 January 2016 at 14:20, Lei Z. [email protected] wrote:

In my case, my requirement is that if users enter C2.name、 C3.name and
C4.name, I should show them A1.name or whatever attributes A might have that
needs to be displayed.

No, still not getting it. When you say user enters C2.name, C3.name
and C4.name do you mean he actually enters the string “C2.name,
C3.name and C4.name” or do you mean he enters actual names or what?
Please give an example of actual records and their fields and values
and exactly what the user might enter and what you want to show.

Colin

On Wednesday, January 13, 2016 at 2:22:51 AM UTC-5, Lei Z. wrote:

I consider that this can be done by using something straightforward like
A.Cs.includes?(C2,C3,C4).

But that requires an iteration of A. And I concern that it would have some
performance issue.

If you want to load matching As without instantiating the Cs, you could
do
something like:

A.where(id: C.where(code: params[:codes]).pluck(:a_id))

If you are going to instantiate all As and Cs found anyway, you could
just
use eager loading:

found_c = C.where(code: params[:codes]).includes(:a)
found_a = found_c.collect(&:a).uniq

Jim

Thank you, I’ll check this out.

A for person, C for organization, which means they both have names.

Like, a person called John Terry, and he is affiliated to three
organizations called Chelsea FC, London Something, and UK Good Football
Player. ( I made up the other two org.)

So now if users want to find out some people that belong to these three
organizations simultaneously, enter “Chelsea FC, London Something, UK
Good
Football Player”, system will show John Terry and other people who might
meat this criteria as well.

Hope this time I make myself clear.

Thank you for your time.

On 14 January 2016 at 02:24, Lei Z. [email protected] wrote:

A for person, C for organization, which means they both have names.

Like, a person called John Terry, and he is affiliated to three
organizations called Chelsea FC, London Something, and UK Good Football
Player. ( I made up the other two org.)

I don’t understand the associations then. Does an organisation have a
number of affiliated people? Does a person have many organisations to
which he is affiliated? If so then you want has_and_belongs_to_many
or has_many_through as I said earlier.

By the way, I would find it easier to follow the thread if you could
not top post, but insert your comments at appropriate places in the
previous post. Thanks.

Colin

On Thursday, January 14, 2016 at 4:55:28 PM UTC+8, Colin L. wrote:

number of affiliated people? Does a person have many organisations to
which he is affiliated? If so then you want has_and_belongs_to_many
or has_many_through as I said earlier.

Yes, I guess I know how to do it now.

By the way, I would find it easier to follow the thread if you could
not top post, but insert your comments at appropriate places in the
previous post. Thanks.

You mean I should reply like this? Got it.

Thank you.

On Wednesday, January 13, 2016 at 12:13:36 PM UTC-5, Jim wrote:

found_c = C.where(code: params[:codes]).includes(:a)
found_a = found_c.collect(&:a).uniq

I missed the requirement that each A found should contain all desired
C
records. These queries will find As with any of the C records found.

Jim Crate

On 14 January 2016 at 14:26, Lei Z. [email protected] wrote:

I don’t understand the associations then. Does an organisation have a
number of affiliated people? Does a person have many organisations to
which he is affiliated? If so then you want has_and_belongs_to_many
or has_many_through as I said earlier.

Yes, I guess I know how to do it now.

Excellent.

By the way, I would find it easier to follow the thread if you could
not top post, but insert your comments at appropriate places in the
previous post. Thanks.

You mean I should reply like this? Got it.

Yes please, the list does not have a specific requirement but
personally I find it much better as one does not have to search down
looking for what is being replied to. For someone asking a question
it is not so much of an issue as they know what they asked but for
those asking who maybe have a dozen questions on the go in a number of
mailing lists then the context of each question is not necessarily
immediately remembered.

Thank you.

Glad to be of help

Colin