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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions