vendredi 23 janvier 2015

rails 4 activerecord group duplicate entries and concat into a column

I'm relatively new to rails and I love ActiveRecord, but I am still getting used to generating ActiveRecord queries equivalent to what I would do in SQLite. I want to rely on ActiveRecord as much as possible since it will be easier to swap out the database in the future. I have the following tables:



Tables

projects
id | title | etc
---+-------+----
1 | foo |

roles
id | name | etc
---+---------+-----
1 | manager |
2 | editor |
3 | author |

users
id | name | etc
---+------+-----
1 | tom |
2 | jerry|

team_memberships
id | project_id | member_id | role_id
---+------------+-----------+---------
1 | 1 | 1 | 1
2 | 1 | 1 | 2
3 | 1 | 2 | 3

*NOTE: member_id is a foreign key of the User model's id


In my Project model, I have a has_many association called team_memberships. A TeamMember can take on multiple Roles for a project. In such a case if I loop through the project's team_memberships (@project.team_memberships.each), I get duplicates members. I want to concat the roles into another column sorted by roles.name asc like so:



Desired output

member_id | roles
-----------+-------------------
2 | author
1 | editor, manager


I have been able to achieve this by using group_by and mapping it into a new array, but that is not grouping via ActiveRecord.



team_member_roles = project.team_memberships.select("roles.name").joins(:role).includes(:role, :member).order("roles.name").group_by(&:member_id).map do | key, memberships |
{ :member => memberships.first.member, :roles => memberships.map {|membership| membership.role.name }.join(",") }
end


How would I accomplish this the ActiveRecord way? Would using group_by be scoffed at? Are there performance issues I should be concerned about? Like I said, I'm new to Rails and I want to make sure that my code not only just works but follows rails conventions.


Aucun commentaire:

Enregistrer un commentaire