5
\$\begingroup\$

I have to call Article.to_draft/to_archive/publish method depending on the presence of the corresponding key in the params hash.

I do, however, have no idea to implement it properly.

def update_state
  method = if params[:draft].present?
             :to_draft
           elsif params[:archived].present?
             :to_archive
           else
             :publish
           end
  @article.send method
end

The code works, but the number of possible states of an article will probably grow in the future.

I would like to have a hash like this:

{ draft: :to_draft, archived: :to_archive, default: :publish }

and let #update_state decide what should be called, based on the params hash.

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

I suggest using find

ARTICLE_ACTIONS = { :draft => :to_draft,
                    :archived => :to_archive,
                    :default => :publish 
                  }

def update_state
  state = [:draft, :archived, :default]
             .find {|state| params[state].present?}
  @article.send ARTICLE_ACTIONS[state]
end
\$\endgroup\$
3
  • \$\begingroup\$ Sorry, I probably didn't explain it well. params is a hash provided by rails controller. it does NOT contain the names of the corresponding methods (:draft => :to_draft etc.). I have to call what's needed manually \$\endgroup\$
    – just so
    Commented Jan 7, 2016 at 14:59
  • \$\begingroup\$ Browser sends an HTTP request, with one of the possible states (draft, archived). Based on this, I have to call one of the @article methods: @article.to_draft if params contains 'draft' or @articleto_archive if params contains archived or @article.publish if none are provided \$\endgroup\$
    – just so
    Commented Jan 7, 2016 at 15:03
  • \$\begingroup\$ @justso you may build the hash yourself, answer updated \$\endgroup\$
    – Caridorc
    Commented Jan 7, 2016 at 15:03
0
\$\begingroup\$

I know the question is already but I think it can be simplified further by using routes. Like

post "article/:state", to: "articles#update_state"

and then you can simply call

["draft", "archived", "default"].includes?(params[:state]) && @article.send(params[:state]) 
\$\endgroup\$
3
  • \$\begingroup\$ It's an security vulnerability \$\endgroup\$
    – just so
    Commented Jan 13, 2016 at 11:07
  • 2
    \$\begingroup\$ A question having an accepted answer isn't a problem, more reviews are always welcome when they have new suggestions like this. \$\endgroup\$ Commented Jan 13, 2016 at 11:09
  • \$\begingroup\$ @justso I think it can be bypassed, I have edited my answer though. \$\endgroup\$
    – usmanali
    Commented Jan 13, 2016 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.