Rails 4 Filtering on has_many through associations

87 views
Skip to first unread message

Ganesh Ranganathan

unread,
Nov 26, 2014, 3:41:07 AM11/26/14
to rubyonra...@googlegroups.com, chen...@googlegroups.com
Hi All,

I have an issue on filtering a has_many through association. My model is as follows

class Group 
   has_and_belongs_to_many :messages
   has_many :tags, through :messages
end

class Message
   has_and_belongs_to_many :tags
end

class Tag
  has_and_belongs_to_many :messages
end

This gives me the tags for all messages in a group. Groups.first.tags . However I want to filter on an attribute in messages (Message.where(:created => '11-11-2014')) based on which tags should be retrieved. Is it possible to do this in a has_many though association? Thanks in advance

Thanks,
Ganesh

Colin Law

unread,
Nov 26, 2014, 5:38:38 AM11/26/14
to rubyonra...@googlegroups.com
On 26 November 2014 at 08:40, Ganesh Ranganathan
Groups.first.messages.where(:created => '11-11-2014').tags

By the way, if you mean :created_at then this will not work as
created_at includes the time, so to get an exact match on 11-11-2014
it would have to be exactly midnight. You will have to use a time
range, and don't forget to watch out for the timezone.

Colin

>
> Thanks,
> Ganesh
>
> --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/rubyonrails-talk/CALFmRoE96wMtKOkxkE7vx%2B7BhduN0kxRvBt08VD3r_a7-NiWBQ%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

Ganesh Ranganathan

unread,
Nov 26, 2014, 6:02:22 AM11/26/14
to rubyonra...@googlegroups.com

On Wed, Nov 26, 2014 at 4:07 PM, Colin Law <cla...@gmail.com> wrote:
Groups.first.messages.where(:created => '11-11-2014').tags

By the way, if you mean :created_at then this will not work as
created_at includes the time, so to get an exact match on 11-11-2014
it would have to be exactly midnight.  You will have to use a time
range, and don't forget to watch out for the timezone.

​Hi Colin,

Thanks for your reply. This won't work since messages would return an ActiveRelation there is no tags method on an active relation.

In my actual code I will use a between two days. I just used a direct equals for simplicity sake​

Thanks,
Ganesh

Ganesh Ranganathan

unread,
Nov 26, 2014, 6:03:37 AM11/26/14
to chen...@googlegroups.com, rubyonra...@googlegroups.com

On Wed, Nov 26, 2014 at 3:13 PM, Ganesh Mohan <ganesh...@gmail.com> wrote:
You can do this 
has_and_belongs_to_many :messages, -> { where(created_at: '11-11-2014') } 

or you can use scope which is much better

​Hi Ganesh,

I tried various scope syntaxes but it didn't work. :(

Can you point me in the right direction, 

Thanks,
Ganesh​

Colin Law

unread,
Nov 26, 2014, 8:20:39 AM11/26/14
to rubyonra...@googlegroups.com
On 26 November 2014 at 11:02, Ganesh Ranganathan
<ganesh.ran...@gmail.com> wrote:
>
> On Wed, Nov 26, 2014 at 4:07 PM, Colin Law <cla...@gmail.com> wrote:
>>
>> Groups.first.messages.where(:created => '11-11-2014').tags
>>
>> By the way, if you mean :created_at then this will not work as
>> created_at includes the time, so to get an exact match on 11-11-2014
>> it would have to be exactly midnight. You will have to use a time
>> range, and don't forget to watch out for the timezone.
>
>
> Hi Colin,
>
> Thanks for your reply. This won't work since messages would return an
> ActiveRelation there is no tags method on an active relation.

You are right of course.

Colin

Ganesh Ranganathan

unread,
Nov 26, 2014, 8:25:28 AM11/26/14
to rubyonra...@googlegroups.com

On Wed, Nov 26, 2014 at 6:49 PM, Colin Law <cla...@gmail.com> wrote:
You are right of course.

​I got the answer from another mailing list. Created a static method on the Tag model

def self.for_groupmessages_created_on(group_id,fromdate,todate)    
                Tag.joins(:messages, :groups).where(
                        messages: {                     
                                created: fromdate..todate       
                        },     
                        groups: {                       
                                id: group_id                    
                        }       
)  

Thanks,
Ganesh​

Reply all
Reply to author
Forward
0 new messages