Poll migration - problem and advice

(Danny Goodall) #1

Hi, my chosen approach to creating polls during a migration is functional but not without issues.

tl;dr - Is there a way that I can call Post.save as if I were a system user (to skip validation) - and is this advisable / desirable?

It seems to me that polls have two stages - setting up the poll and then voting.

Setting up the poll has two components

  1. placing the [poll]...[/poll] tag into the Post raw / cooked fields - usually keyed in by our users
  2. recording the details of the options and votes in a PostCustomField under the [polls] hash structure - usually handled by our polls plugin

Once these structures are in place, it is then possible to record votes against the poll using the DiscoursePoll::Poll.vote method.

The approach I took to handle step 1 of the Setting up the poll component was to simply append the [poll]...[/poll] text to the raw field of the Post in question.

Once this is saved and the raw content cooked, the Poll plugin will do its thing and create the hash structure mentioned in step 2 above.

I also had to adjust the poll_minimum_trust_level_to_create site setting so that my newly migrated level 0 users were able to create polls.

However, now that I have got this far, the act of re-saving the Post so that the [poll]…[/poll] elements are generated is tripping Post.save validation problems.

These validation problems were not an issue for the migrator as it seems to run as a system level Guardian user.

An example is where my trust level 0 users cannot mention more than two other users in a post. This wasn’t a problem in the forum I’m migrating from and neither was it a problem for the post migrator as it uses PostCreator as system user.

I’ve tried to follow the logic of the phpbb3 poll importer to see how it does its stuff, but I’m new to Ruby and only a part-time hacker.

It looks like it re-produces the work of the poll plugin in creating the [polls] hash structure in the post custom field which I’m loathed to do.

Ideally, what I’d like to do is re-save the post (with the added [poll]...[/poll] text) as a system user so that the validation isn’t fired. Alternatively I’d like to call Post.save and skip user level validation.

Is that possible?

Any advice gratefully received.

(Danny Goodall) #2

OK, a little more information.

I’ve now found the :validate => false parameter to Post.save.

As expected, it bypasses the validation and saves the post, but in doing so it seems to stop the poll plugin from creating the [poll] structure in the PostCustomField row.

Any other ideas?

I’m thinking that I could change the post ownership to a level 4 or system user, carry out my poll actions, and then change the ownership back with validation turned off, but this is already feeling a bit hacky.

(Régis Hanol) #3

Disabling the validation should not prevent the poll to be created. Can you show us the code? Maybe there’s an error elsewhere.

(Gerhard Schlager) #4

I think the poll is created in a post-processing step. @bletch There was a reason why I wrote the phpbb3 importer that way and if I remember correctly, I had the same problem you’re having right now.

(Danny Goodall) #5

I will do once I’ve setup some test data and reached some concrete conclusions about what is going on as it seems to be only failing on posts that fail the trust level 0 validation.


(Danny Goodall) #6

OK, I’ve now got this working by implementing a few workarounds but it’s not clear why some things didn’t just work.

Previously, I was running the poll creation routine against already migrated posts which meant editing them and occasionally tripping the user trust_level validation.

I decided to move the poll creation routine into my post migration code so that I could use the PostCreator class which I knew runs as a system user.

I did this, created a valid [poll]...[/poll] structure and added it at the end of the .raw post content. Discourse picked up the poll, cooked the content so that it rendered correctly on the screen, and I thought I’d solved it.

However, despite rendering on screen like a poll, it would not accept votes. Looking in the database there was no corresponding [polls] hash structure in the PostCustomFields table. So there would be no way to record my votes.

If I then used the Discourse UI to make any minor change to the raw content that would force the Polls plugin to fire the post changed code, as soon as the edit was complete the poll UI allowed me to vote and the [polls] structure appeared in the PostCustomFields table.

I decided that I would implement a :post_create_action call back on the newly created post and edit it as an elevated user. I simply elevated the user to trust_level 4, added a markdown horizontal rule at the foot of the raw post content, saved it, reset the trust_level and it’s worked. The poll now renders fully, creates the [polls] structure in PostCustomField and accepts my migrated votes.

Why the full poll creation routine doesn’t fire after PostCreator finishes, but instead needs the post to be edited, I don’t know.

Thanks again for you support. :+1: