Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify the instantiation of PersonCard objects #15603

Merged
merged 7 commits into from
Jan 26, 2017
Merged

Conversation

mhl
Copy link
Contributor

@mhl mhl commented Jan 17, 2017

What does this do?

This pull request simplifies the dependencies of the PersonCard class,
so that it only needs to take a Person and a LegislativePeriod when
instantiating. It also moves some functionality from TermTable to
LegislativePeriod (by monkey-patching the latter class).

Why was this needed?

In the future we would like to reuse these models in other projects, and
these changes make that reuse easier.

Relevant Issue(s)

I couldn't find one, but some of these changes were suggested by "TODO"
comments in the existing source.

Implementation notes

I'm not 100% sure if the monkey-patching of LegislativePeriod is sensible
or not - maybe similar changes in the original class in everypolitician-ruby
would be more useful in the long run, but I thought this was OK.

Screenshots

The appearance of the site should be unchanged by these.

Notes to Reviewer

I've run the recursive wget on the site before and after this change, and
the results are identical (according to diff -r) so I don't think this has
broken anything.

I'm not sure if the upgrade of everypolitician-popolo is actually required
any more (I've gone through several variants of this change) but it seems
like a good idea in any case.

Notes to Merger

None.

@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 17, 2017 20:04 Inactive
@mhl mhl added the 3 - WIP label Jan 17, 2017
@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 17, 2017 21:20 Inactive
Copy link
Contributor

@tmtmtmtm tmtmtmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this @mhl — it's been on my wishlist for quite some time! I have a very slight concern that upgrading to the latest everypolitician-popolo leaves us with a bunch of local workarounds to things that are no longer true with that version, but as the tests all pass, and there are no changes when generating the static site, it's probably OK to go ahead with this and then have look separately at cleaning those up.

A few comments in-place for things that are largely stylistic (at this stage in this project I'm keen to maintain consistency), or where having upgraded everypolitician-popolo I think you should be able to simplify some things even more, but the underlying approach looks good.


module Everypolitician
class LegislativePeriod
def people_ids
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this method is only used within people here, so could be private. (If needed at all — see later comment)

@people_ids ||= Set.new(memberships.map(&:person_id))
end

def people
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we now have the latest everypolitician-popolo, I think this could just be memberships.map(&:person).uniq(&:id), now, with no need for the people_ids method.

@top_identifiers = top_identifiers # get from Legislature
@term = term
@legislature = term.legislature
@top_identifiers = term.top_identifiers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies that the coding style isn't well documented anywhere, but in this project we try to maintain very strong encapsulation — restricting instance variables to only things passed directly to the constructor, and even then always accessing those through (ideally private) accessor methods, rather than directly. We also try to avoid doing work in the constructor other than initialising those variables. So here, I'd prefer legislature and top_identifiers to be methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -39,6 +41,10 @@ def identifiers
Section::Identifiers.new(person, top_identifiers: top_identifiers).data
end

def memberships
@person.memberships.select { |m| m.term.id == @term.id }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than rolling your own select here, it's probably better to go through the public search interface: i.e. @person.memberships.where(legislative_period_id: term.id)

@@ -3,6 +3,35 @@
require_relative '../everypolitician_extensions'
require_relative '../person_cards'

# Reopen the LegislativePeriod class to add helper methods; we could
# consider adding some of these to the class definition in
# everypolitician-ruby instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than re-opening here, I think it would be better to add these into lib/everypolitician_extensions.rb, especially as we're already extending LegislativePeriod there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I hadn't spotted that (despite actually using the memberships method defined there!)

@mhl mhl force-pushed the simplify-personcard branch from 6006c59 to b0275cc Compare January 18, 2017 12:26
@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 18, 2017 12:26 Inactive
@mhl
Copy link
Contributor Author

mhl commented Jan 18, 2017

Thanks for all those helpful comments, @tmtmtmtm - it was too confusing to amend these via fixups so I've pushed a new version of the branch.

I've tried diffing this generated version with the other and there are some changes:

  1. Sometimes the order of two people with an identical sort_name is reversed (e.g. Octavio Jara Wolff and Sergio Jara Catalán)
  2. Sometime the top identifiers are in a different order. In the examples I've looked at this is similarly because there there the same number of those identifiers.

These are both due to the following returning people in different orders:

# On master:
popolo.persons.select { |p| Set.new(term.memberships.map(&:person_id)).include?(p.id) }
# On simplify-personcard
term.memberships.map(&:person).uniq(&:id)

The top identifiers and persons are futher sorted before use, so this only has an effect where the sort key is the same for two different items. The differences in output are pretty inconsequential, I think, but to potentially reduce the time spent in looking into similar problems in the future, I'd be tempted to add:

diff --git a/lib/everypolitician_extensions.rb b/lib/everypolitician_extensions.rb
index 6928a06..c8ef4d7 100644
--- a/lib/everypolitician_extensions.rb
+++ b/lib/everypolitician_extensions.rb
@@ -49,7 +49,7 @@ module EveryPolitician
                            .flatten
                            .reject { |i| i[:scheme] == 'everypolitician_legacy' }
                            .group_by { |i| i[:scheme] }
-                           .sort_by { |_s, ids| -ids.size }
+                           .sort_by { |s, ids| [-ids.size, s] }
                            .map { |s, _ids| s }
     end
   end
diff --git a/lib/page/term_table.rb b/lib/page/term_table.rb
index 0e9e0b4..4e0c28d 100644
--- a/lib/page/term_table.rb
+++ b/lib/page/term_table.rb
@@ -56,7 +56,7 @@ module Page
     end
 
     def people
-      @people ||= term.people.sort_by(&:sort_name).map do |person|
+      @people ||= term.people.sort_by{|e| [e.sort_name, e.name]}.map do |person|
         PersonCard.new(
           person: person,
           term:   term

What do you think?

@tmtmtmtm
Copy link
Contributor

@mhl yes, I think stabilising the sort order is a good idea.

@mhl mhl force-pushed the simplify-personcard branch 2 times, most recently from 008cc48 to 3c27ddf Compare January 19, 2017 11:12
@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 19, 2017 11:12 Inactive
@mhl mhl force-pushed the simplify-personcard branch from 3c27ddf to e1e3ce0 Compare January 19, 2017 11:22
@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 19, 2017 11:22 Inactive
@mhl mhl force-pushed the simplify-personcard branch from e1e3ce0 to b486efa Compare January 19, 2017 13:38
@tmtmtmtm tmtmtmtm temporarily deployed to everypolitician-viewe-pr-15603 January 19, 2017 13:38 Inactive
def top_identifiers
term.top_identifiers
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not catching this earlier, but I'm not convinced that these need to be public, do they?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - thanks. I've force-pushed a version that changes those two methods to be private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, except probably memberships should be private too, grr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, no - it's used by the term_table.erb view.

@tmtmtmtm I think / hope this is OK now!

mhl added 6 commits January 26, 2017 10:53
The displayed positions should only be for a particular term, however,
so we need to pass 'term' as well, to select memberships for that term.
This isn't a bad thing, though, because in subsequent commits 'term'
will be useful for getting the legislature, country, proxy image URL
and the top identifiers.
We can derive the proxy image URL from the country, legislature and
person ID, and the former two can be found from the term.
These methods:

  top_identifiers
  current_term_memberships
  current_term_people_ids
  people_for_current_term

... all operate on data specific to a term; those that are still needed
can be moved to the LegislativePeriod and then they can be used wherever
a term object is available.
Thanks to @tmtmtmtm for pointing out that the people method can be
much simpler, making the people_ids method unnecessary.
This is now directly available from the LegislativePeriod object (called
'term') so there's no need to pass it to the initializer.
Rubocop complained about the following things:

  lib/page/term_table.rb:90:11: C: Align the elements of a hash literal if they span more than one line.
            person:          person,
            ^^^^^^^^^^^^^^^^^^^^^^^
  lib/page/term_table.rb:91:11: C: Align the elements of a hash literal if they span more than one line.
            term:            term,
            ^^^^^^^^^^^^^^^^^^^^^
  lib/page/term_table.rb:91:32: C: Avoid comma after the last parameter of a method call.
            term:            term,
                                 ^

This commit fixes those errors in a way that seems to fit the local
style in this file.
Copy link
Contributor

@tmtmtmtm tmtmtmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Woot! Thanks @mhl

@tmtmtmtm tmtmtmtm merged commit 8e9823e into master Jan 26, 2017
@tmtmtmtm tmtmtmtm removed the 3 - WIP label Jan 26, 2017
@tmtmtmtm tmtmtmtm deleted the simplify-personcard branch December 16, 2017 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants