diff --git a/app/controllers/bubbles_controller.rb b/app/controllers/bubbles_controller.rb
index f65d925..f3fe14f 100644
--- a/app/controllers/bubbles_controller.rb
+++ b/app/controllers/bubbles_controller.rb
@@ -9,6 +9,11 @@ class BubblesController < ApplicationController
@bubble = Bubble.new
end
+ def show
+ @bubble = Bubble.find(params[:id])
+ @spendings = @bubble.spendings.unscope(:order).order(created_at: :desc)
+ end
+
def create
if Bubble.new(allowed_params).save
redirect_to bubbles_path, flash: { success: "Créé" }
diff --git a/app/controllers/spendings_controller.rb b/app/controllers/spendings_controller.rb
new file mode 100644
index 0000000..0b18e97
--- /dev/null
+++ b/app/controllers/spendings_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class SpendingsController < ApplicationController
+ def new
+ @bubble = Bubble.find(params[:bubble_id])
+ @spending = Spending.new
+ end
+
+ def create
+ @bubble = Bubble.find(params[:bubble_id])
+ if @bubble.spendings.new(allowed_params).save
+ redirect_to bubble_path(@bubble), flash: { success: "Créé" }
+ else
+ redirect_to new_bubble_spending_path(@bubble), flash: { error: "Pas créé" }
+ end
+ end
+
+ private
+
+ def allowed_params
+ params.require(:spending).permit(:amount, :description, :owner_id)
+ end
+end
diff --git a/app/models/bubble.rb b/app/models/bubble.rb
index 36c360d..59181b7 100644
--- a/app/models/bubble.rb
+++ b/app/models/bubble.rb
@@ -21,4 +21,5 @@
class Bubble < ApplicationRecord
validates :name, presence: true, allow_blank: false
belongs_to :owner, class_name: "User"
+ has_many :spendings
end
diff --git a/app/models/spending.rb b/app/models/spending.rb
new file mode 100644
index 0000000..078a6a1
--- /dev/null
+++ b/app/models/spending.rb
@@ -0,0 +1,25 @@
+# == Schema Information
+#
+# Table name: spendings
+#
+# id :uuid not null, primary key
+# amount :decimal(, ) default(0.0), not null
+# description :text default(""), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# bubble_id :uuid not null
+# owner_id :uuid not null
+#
+# Indexes
+#
+# index_spendings_on_bubble_id (bubble_id)
+# index_spendings_on_owner_id (owner_id)
+#
+# Foreign Keys
+#
+# fk_rails_... (owner_id => users.id)
+#
+class Spending < ApplicationRecord
+ belongs_to :owner, class_name: "User"
+ belongs_to :bubble
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9aac96e..cd3ef09 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -23,4 +23,5 @@ class User < ApplicationRecord
:recoverable, :rememberable, :validatable
has_many :bubbles, foreign_key: :owner_id
+ has_many :spendings, foreign_key: :owner_id
end
diff --git a/app/views/bubbles/index.html.erb b/app/views/bubbles/index.html.erb
index 2e8ea97..784bd02 100644
--- a/app/views/bubbles/index.html.erb
+++ b/app/views/bubbles/index.html.erb
@@ -11,6 +11,7 @@
<%= bubble.name %> |
<%= bubble.description %> |
+ <%= link_to "Voir", bubble_path(bubble) %>
<%= link_to "Éditer", edit_bubble_path(bubble) %>
<%= link_to "Supprimer", bubble_confirm_destroy_path(bubble) %>
|
diff --git a/app/views/bubbles/show.html.erb b/app/views/bubbles/show.html.erb
new file mode 100644
index 0000000..e13d15e
--- /dev/null
+++ b/app/views/bubbles/show.html.erb
@@ -0,0 +1,22 @@
+<%= @bubble.name %>
+<%= @bubble.description %>
+<%= link_to "Nouvelle dépense", new_bubble_spending_path(@bubble) %>
+
+
+
+
+ Montant |
+ Origine |
+ Raison |
+
+
+
+ <% @spendings.each do |spending| %>
+
+ <%= number_to_currency(spending.amount, unit: "€") %> |
+ <%= spending.owner.email %> |
+ <%= spending.description %> |
+
+ <% end %>
+
+
diff --git a/app/views/spendings/new.html.erb b/app/views/spendings/new.html.erb
new file mode 100644
index 0000000..3d2b31d
--- /dev/null
+++ b/app/views/spendings/new.html.erb
@@ -0,0 +1 @@
+<%= render partial: "spendings/shared/form", locals: { spending: @spending, bubble: @bubble } %>
\ No newline at end of file
diff --git a/app/views/spendings/shared/_form.html.erb b/app/views/spendings/shared/_form.html.erb
new file mode 100644
index 0000000..e214a25
--- /dev/null
+++ b/app/views/spendings/shared/_form.html.erb
@@ -0,0 +1,20 @@
+<%= form_for spending, url: spending.persisted? ? spending_path(spending) : bubble_spendings_path(bubble) do |f| %>
+
+
+ <%= f.label :amount, "Valeur" %>
+ <%= f.number_field :amount, required: true, step: 0.01 %>
+
+
+
+ <%= f.label :description, "Description" %>
+ <%= f.text_area :description %>
+
+
+
+ <%= f.label :owner_id, "Créateur" %>
+ <%= f.select :owner_id, User.all.collect {|u| [ u.email, u.id ] }, selected: bubble.owner_id || current_user.id %>
+
+
+ <%= f.submit "Sauvegarder" %>
+
+<% end %>
\ No newline at end of file
diff --git a/config/application.rb b/config/application.rb
index a03efd1..d3df40c 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -18,5 +18,7 @@ module DebtManager
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
+
+ config.i18n.default_locale = :fr
end
end
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
new file mode 100644
index 0000000..33c7948
--- /dev/null
+++ b/config/locales/fr.yml
@@ -0,0 +1,221 @@
+---
+fr:
+ activerecord:
+ errors:
+ messages:
+ record_invalid: 'La validation a échoué : %{errors}'
+ restrict_dependent_destroy:
+ has_one: Vous ne pouvez pas supprimer l'enregistrement car un(e) %{record}
+ dépendant(e) existe
+ has_many: Vous ne pouvez pas supprimer l'enregistrement parce que les %{record}
+ dépendants existent
+ date:
+ abbr_day_names:
+ - dim
+ - lun
+ - mar
+ - mer
+ - jeu
+ - ven
+ - sam
+ abbr_month_names:
+ -
+ - jan.
+ - fév.
+ - mars
+ - avr.
+ - mai
+ - juin
+ - juil.
+ - août
+ - sept.
+ - oct.
+ - nov.
+ - déc.
+ day_names:
+ - dimanche
+ - lundi
+ - mardi
+ - mercredi
+ - jeudi
+ - vendredi
+ - samedi
+ formats:
+ default: "%d/%m/%Y"
+ long: "%-d %B %Y"
+ short: "%-d %b"
+ month_names:
+ -
+ - janvier
+ - février
+ - mars
+ - avril
+ - mai
+ - juin
+ - juillet
+ - août
+ - septembre
+ - octobre
+ - novembre
+ - décembre
+ order:
+ - :day
+ - :month
+ - :year
+ datetime:
+ distance_in_words:
+ about_x_hours:
+ one: environ une heure
+ other: environ %{count} heures
+ about_x_months:
+ one: environ un mois
+ other: environ %{count} mois
+ about_x_years:
+ one: environ un an
+ other: environ %{count} ans
+ almost_x_years:
+ one: presque un an
+ other: presque %{count} ans
+ half_a_minute: une demi‑minute
+ less_than_x_seconds:
+ zero: moins d'une seconde
+ one: moins d'une seconde
+ other: moins de %{count} secondes
+ less_than_x_minutes:
+ zero: moins d'une minute
+ one: moins d'une minute
+ other: moins de %{count} minutes
+ over_x_years:
+ one: plus d'un an
+ other: plus de %{count} ans
+ x_seconds:
+ one: "%{count} seconde"
+ other: "%{count} secondes"
+ x_minutes:
+ one: "%{count} minute"
+ other: "%{count} minutes"
+ x_days:
+ one: "%{count} jour"
+ other: "%{count} jours"
+ x_months:
+ one: "%{count} mois"
+ other: "%{count} mois"
+ x_years:
+ one: "%{count} an"
+ other: "%{count} ans"
+ prompts:
+ second: Seconde
+ minute: Minute
+ hour: Heure
+ day: Jour
+ month: Mois
+ year: Année
+ errors:
+ format: "%{attribute} %{message}"
+ messages:
+ accepted: doit être accepté(e)
+ blank: doit être rempli(e)
+ confirmation: ne concorde pas avec %{attribute}
+ empty: doit être rempli(e)
+ equal_to: doit être égal à %{count}
+ even: doit être pair
+ exclusion: n'est pas disponible
+ greater_than: doit être supérieur à %{count}
+ greater_than_or_equal_to: doit être supérieur ou égal à %{count}
+ in: doit être dans l'intervalle %{count}
+ inclusion: n'est pas inclus(e) dans la liste
+ invalid: n'est pas valide
+ less_than: doit être inférieur à %{count}
+ less_than_or_equal_to: doit être inférieur ou égal à %{count}
+ model_invalid: 'Validation échouée : %{errors}'
+ not_a_number: n'est pas un nombre
+ not_an_integer: doit être un nombre entier
+ odd: doit être impair
+ other_than: doit être différent de %{count}
+ present: doit être vide
+ required: doit exister
+ taken: est déjà utilisé(e)
+ too_long:
+ one: est trop long (pas plus d'un caractère)
+ other: est trop long (pas plus de %{count} caractères)
+ too_short:
+ one: est trop court (au moins un caractère)
+ other: est trop court (au moins %{count} caractères)
+ wrong_length:
+ one: ne fait pas la bonne longueur (doit comporter un seul caractère)
+ other: ne fait pas la bonne longueur (doit comporter %{count} caractères)
+ template:
+ body: 'Veuillez vérifier les champs suivants : '
+ header:
+ one: 'Impossible d''enregistrer ce(tte) %{model} : %{count} erreur'
+ other: 'Impossible d''enregistrer ce(tte) %{model} : %{count} erreurs'
+ helpers:
+ select:
+ prompt: Veuillez sélectionner
+ submit:
+ create: Créer un(e) %{model}
+ submit: Enregistrer ce(tte) %{model}
+ update: Modifier ce(tte) %{model}
+ number:
+ currency:
+ format:
+ delimiter: " "
+ format: "%n %u"
+ precision: 2
+ separator: ","
+ significant: false
+ strip_insignificant_zeros: false
+ unit: "€"
+ format:
+ delimiter: " "
+ precision: 3
+ round_mode: default
+ separator: ","
+ significant: false
+ strip_insignificant_zeros: false
+ human:
+ decimal_units:
+ format: "%n %u"
+ units:
+ billion: milliard
+ million: million
+ quadrillion: million de milliards
+ thousand: millier
+ trillion: billion
+ unit: ''
+ format:
+ delimiter: ''
+ precision: 3
+ significant: true
+ strip_insignificant_zeros: true
+ storage_units:
+ format: "%n %u"
+ units:
+ byte:
+ one: octet
+ other: octets
+ eb: Eo
+ gb: Go
+ kb: ko
+ mb: Mo
+ pb: Po
+ tb: To
+ percentage:
+ format:
+ delimiter: ''
+ format: "%n%"
+ precision:
+ format:
+ delimiter: ''
+ support:
+ array:
+ last_word_connector: " et "
+ two_words_connector: " et "
+ words_connector: ", "
+ time:
+ am: am
+ formats:
+ default: "%d %B %Y %Hh %Mmin %Ss"
+ long: "%A %d %B %Y %Hh%M"
+ short: "%d %b %Hh%M"
+ pm: pm
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 925f211..a4d5f9a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -6,7 +6,8 @@ Rails.application.routes.draw do
# Defines the root path route ("/")
get :home, controller: :profile
- resources :bubbles, except: [:show] do
+ resources :bubbles do
+ resources :spendings, only: [:new, :create]
get :confirm_destroy
end
end
diff --git a/db/migrate/20231231172005_add_spending_to_bubbles.rb b/db/migrate/20231231172005_add_spending_to_bubbles.rb
new file mode 100644
index 0000000..b90fee4
--- /dev/null
+++ b/db/migrate/20231231172005_add_spending_to_bubbles.rb
@@ -0,0 +1,12 @@
+class AddSpendingToBubbles < ActiveRecord::Migration[7.0]
+ def change
+ create_table :spendings, id: :uuid do |t|
+ t.decimal :amount, null: false, default: 0
+ t.text :description, null: false, default: ""
+ t.references :bubble, type: :uuid, null: false
+ t.references :owner, type: :uuid, foreign_key: { to_table: :users }, null: false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 90d32be..91001f3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_12_10_091848) do
+ActiveRecord::Schema[7.0].define(version: 2023_12_31_172005) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
@@ -25,6 +25,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_12_10_091848) do
t.index ["owner_id"], name: "index_bubbles_on_owner_id"
end
+ create_table "spendings", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+ t.decimal "amount", default: "0.0", null: false
+ t.text "description", default: "", null: false
+ t.uuid "bubble_id", null: false
+ t.uuid "owner_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["bubble_id"], name: "index_spendings_on_bubble_id"
+ t.index ["owner_id"], name: "index_spendings_on_owner_id"
+ end
+
create_table "users", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
@@ -38,4 +49,5 @@ ActiveRecord::Schema[7.0].define(version: 2023_12_10_091848) do
end
add_foreign_key "bubbles", "users", column: "owner_id"
+ add_foreign_key "spendings", "users", column: "owner_id"
end