Search code examples
ruby-on-railsruby-on-rails-plugins

Accessing a parameter within a plugin


I'm trying to modify the vestal_versions plugin to accept a parameter I set upon saving. This parameter will act as a new flag to determine when to create a revision upon updating. Currently it will always run upon update when a new revision is needed. Here is the affected area of unmodified plugin code:

after_update :create_version, :if => :needs_version?

    def create_version
        versions.create(:changes => changes.slice(*versioned_columns), :number => (last_version + 1))
        reset_version
    end 

The parameter I am sending in the view upon submit is "forcerevision=n". How would I pull in this parameter and what conditional would I use to allow this to only run when "forcerevision=y"? It seems it would be cleanest to modify the after_update filter?

Here is the log of the data being passed on update.

Processing NotesController#update (for 521.0.0.1 at 2009-12-05 13:25:45) [PUT]
Parameters: {"authenticity_token"=>"#########################+k=", "id"=>"4", "forcerevision"=>"n", "note"=>{"notebook_id"=>"", "public"=>"n", "body"=>"A versioned note", "title"=>"Version Note Test", "flag"=>"important", "star"=>"false", "tag_list"=>""}}

vestal_versions on Github


Solution

  • The cleanest way to do this would be to add an attr_accessor when a model is declared to be versioned.

    Then override needs_version? to check that attribute.

    Anywhere in LaserLemon::VestalVersions::ClassMethods#versioned add this line:

    attr_accessor :force_reversion
    

    Then rewrite LaserLemon::VestalVersions::InstanceMethods#needs_version? to check this attribute:

    N.B. due to the way checkboxes are handled "0" is considered false for checkboxes, and boolean fields, but is a true value in ruby. So we can't just check if force_reversion does not evaluate to false.

    def needs_version?
      !(versioned_columns & changed).empty? || 
        ![nil, "0", 0, false].include?(force_reversion)
    end
    

    And you're all set. Just pass any value for force_reversion as if it were a column.

    After the above changes with the following model:

    class User

    @user.update_attributes(:force_reversion => true, :unversioned_column => new_value)
    

    Or in a form:

    <%= form_for @user do |f| %>
      <%= f.label :force_reversion, "Force New Version" %>
      <%= f.check_box :force_reversion %>
      ... More fields ...
    <% end %>