Controlando minhas finanças com Rails

Usando Ruby para me ajudar a controlar meu dinheiro

Todo ínicio de ano eu sempre me deparo o quão negligente fui com meu dinheiro no ano anterior e tento usar alguma planilha ou aplicativo para tentar controlar minhas finanças, mas geralmente acabo falhando, seja pelo fato de não gostar de planilhas(sou ruim no Excel 😅), ou pelo fato dos aplicativos geralmente possuirem o modelo FREEMIUM* de négocio.

Esse ano decidi que vou fazer um controle melhor, e como estou de recesso do trabalho devido as festividades de 🎉 fim de ano 🎉, vou ter um tempinho pra fazer isso.

Passos íniciais

Pensei em criar uma aplicação básica de ínicio para evitar um conflito desnecessário comigo mesmo em procrastinar no desenvolvimento.

A primeira coisa que pensei foi qual tecnologias iria usar para o desenvolvimento da aplicação web. Mais uma vez pensando na simplicidade e praticidade pensei em Ruby, mais especificamente o Ruby on Rails.

Muito por ser um framework Fullstack, que me permite criar um monolito, sem precisar criar um backend e um frontend, pois não quero gastar com hospedagem mais que o básico e facilitar minha vida pra aproveitar o fim de ano.

Então acabei decidindo que iria usar o Rails, Bootstrap e Postgres como tecnologias principais.

Pronto, agora com a tecnologia escolhida e meio que por default, já fiz algumas escolhas baseada na mesma,como o banco de dados Postgres e para o frontend fui de Bootstrap, usei bastante no passado e ele ajudava muito pra quem não é full frontend, já com algumas classes defaults e estilos definidos.

Tabelas

Pensei em três tabelas iniciais para representar minhas finanças:

  • Category -> Onde salvarei as categorias com que gastei ou ganhei dinheiro. Ex: Alimentação
  • MoneyIn - > Com o que ganhei dinheiro, Ex: salário, freela.
  • MoneyOut -> Com o que gastei dinheiro, Ex: Ps5

Representação básica das tabelas

Desenvolvimento

Após rodar os comandos iniciais do rails de inicialização do projeto

rails new projeto
cd projeto/
bundle install

Vamos criar as tabelas e a estrutura básica

rails g scaffold categoy name description
rails g scaffold money_in label description amount:float category_id:references money_date:date
rails g scaffold money_out label description amount:float category_id:references money_date:date

Pronto, com isso já temos o Crud básico, agora só precisamos estilizar com bootstrap e adicionar alguns gráficos com a gem Chartkick.

Também adicionei a gem de busca Ransack para facilitar as buscas e criei um formulário de busca para Receitas e Despesas, com alguns filtros que achei legais no momento.

<%= search_form_for @q do |f| %>

  <%= f.label :label_or_description_cont, "Descrição Ou Nome", class: "form-label" %>
  <%= f.search_field :label_or_description_cont, class: "form-control" %>

  <div class="row mt-2">
    <div class="col-md-6">
      <%= f.label :money_date_gteq, "Data Inicial", class: "form-label" %>
      <%= f.search_field :money_date_gteq, type: :date, class: "form-control" %>
    </div>
    <div class="col-md-6">
      <%= f.label :money_date_lteq, "Data Final", class: "form-label" %>
      <%= f.search_field :money_date_lteq, type: :date, class: "form-control" %>
    </div>
  </div>

  <%= f.label :category_id_eq, "Categoria", class: "form-label" %>
  <%= f.select :category_id_eq, options_from_collection_for_select(@categories, :id, :name, params.dig(:q, :category_id_eq)), { include_blank: "Todas" }, class: "form-select" %>

  <div class="row mt-2">
    <div class="col-md-6">
      <%= f.label :amount_gteq, "Valor Mínimo", class: "form-label" %>
      <%= f.search_field :amount_gteq, type: :number, step: :any, class: "form-control" %>
    </div>
    <div class="col-md-6">
      <%= f.label :amount_lteq, "Valor Máximo", class: "form-label" %>
      <%= f.search_field :amount_lteq, type: :number, step: :any, class: "form-control" %>
    </div>
  </div>

  <%= f.submit "Buscar", class: "btn btn-primary mt-2" %>
<% end %>

Também fiz modificações no controller para usar essa busca.

  def index
    @q = MoneyIn.includes(:category).ransack(params[:q])
    @pagy, @money_ins = pagy(@q.result.order(created_at: :desc))
    @categories = Category.all
  end 

Agora com essa busca feita, vamos tentar colocar alguns gráficos para eu tirar algum insight quando for analisar meus gastos.

Com a gem chartkick, que cria gráficos bem legais sem nenhuma burocracia, basta fazer as queries e enviar para o front.

  def money_out_by_category
    MoneyOut
      .joins(:category)
      .where(money_date: @month_start..@month_end)
      .group("categories.name")
      .sum(:amount)
  end

Um exemplo é essa query que faz um somatório de todas as despesas agrupadas por categorias.

Que acaba ficando assim no front:

<%= pie_chart @money_out_by_category %>

Bem simples né!!

Pretendo fazer mais algumas melhorias, como I18n, melhorias no dashboard e outras coisas, tudo isso vai depender bastante do meu tempo esse ano.

Também já hospedei , mas vou deixar pra explicar numa próxima vez.

Se quiser acompanhar meu desenvolvimento, o repositório do projeto tá público e se chama my_money (sou ruim com nomes).

Vlw Flw !!!

Legenda:

FREEMIUM = é um modelo de negócio que oferece um produto ou serviço básico gratuitamente, atraindo muitos usuários, mas cobra por recursos avançados, funcionalidades extras.