Skip to content

Possibility to pass optional arguments in step_to #172

@luizcarvalho

Description

@luizcarvalho

Hello my friends,

Me again :P

During all that I used Stealth, has a functionality that I always missed. The possibility of passing a parameter to another flow action.

For example, when I work with dynamic items as a product listing. This would be my controller:

class ProductsController < BotController

  def say_products
    @products = Product.all
    send_replies
  end

  def say_product_details
    @product = Product.find(number: 1)
    send_replies
  end

end

And this, my reply.

<% if @products.count > 1  %>

- reply_type: list
  top_element_style: compact
  elements:
    <% @products.each do |product|  %>
    - title: "<%= product.name %>"
      subtitle: "🏷 <%= product.description %>"
      buttons:
        - type: "payload"
          text: 'Details'
          payload: PRODUCT_DETAILS_<%= product.number %>"
    <% end  %>

<% else  %>
<% product =  @products.first  %>

- reply_type: text
  text: |
    Name: <%= product.name %>
    Description: <%= product.description %>
    Size: <%= product.size %>
    Color: <%= product.color %>
  buttons:
    - type: "payload"
      text: 'Buy'
      payload: BUY_PRODUCT_<%= product.number %>"
    - type: "payload"
      text: 'Back'
      payload: LIST_PRODUCTS
<% end  %>

This is a little ugly to me and not reusable. I need copy and paste parte this code in product_details.yml and, every that this change, change in all other parte of project

A see a, maybe, better way to do this. If we could pass a product id with a params, and control this in controller, otherwise replies? Like this (is only a example to illustrate the case):

class ProductsController < BotController

  def say_products
    @products = Product.all
    if @products.count > 1
      send_replies
    elsif @products.count = 1
      step_to action: :say_product_details, params: { product_id: @products.last.number }
    else
      step_to action: :say_no_products
    end
  end

  def say_product_details
    @product = Product.find(number: 1)
    send_replies
  end

  def say_no_products
    send_replies
  end

end

Some like this. Controller would orchestrate information and replies are only responsible for formatting them, and thus would better separation of responsibilities.

say_products.yml.erb only this:

- reply_type: list
  top_element_style: compact
  elements:
    <% @products.each do |product|  %>
    - title: "<%= product.name %>"
      subtitle: "🏷 <%= product.description %>"
      buttons:
        - type: "payload"
          text: 'Details'
          payload: PRODUCT_DETAILS_<%= product.number %>"
    <% end  %>

And say_product_details.yml.erb only this.

- reply_type: text
  text: |
    Name: <%= product.name %>
    Description: <%= product.description %>
    Size: <%= product.size %>
    Color: <%= product.color %>
  buttons:
    - type: "payload"
      text: 'Buy'
      payload: BUY_PRODUCT_<%= product.number %>"
    - type: "payload"
      text: 'Back'
      payload: LIST_PRODUCTS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions