diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e1b823c..993c28f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -21,7 +21,7 @@ class ApplicationController < ActionController::Base def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) { |u| u.permit( :nickname, :name, :last_name, :password, :password_confirmation, - :current_password, :avatar + :avatar ) } devise_parameter_sanitizer.for(:account_update) { |u| u.permit( diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index f86f7b4..524168f 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -5,10 +5,10 @@ class OrdersController < ApplicationController @user = User.find(params[:user_id]) @order = @user.orders.build @products = Product.all - @order_products = @order.order_products + @order_items = @order.order_items @products.each do |p| - @order_products.build(product: p) + @order_items.build(product: p) end end @@ -16,7 +16,7 @@ class OrdersController < ApplicationController @user = User.find(params[:user_id]) @order = @user.orders.build(order_params) @products = Product.all - @order_products = @order.order_products + @order_items = @order.order_items if @order.save flash[:success] = "#{@order.to_sentence} ordered. Enjoy it!" @@ -57,6 +57,6 @@ class OrdersController < ApplicationController private def order_params - params.require(:order).permit(order_products_attributes: [:count, product_attributes: [:id, :price, :stock]]) + params.require(:order).permit(order_items_attributes: [:count, product_attributes: [:id, :price, :stock]]) end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e934d1c..f2370db 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,8 +4,8 @@ class UsersController < ApplicationController def show @user = User.find_by_id(params[:id]) || current_user @orders = @user.orders.includes(:products).paginate(page: params[:page]) - @products = @user.products.select("products.*", "sum(order_products.count) as count").group(:product_id) - @categories = @user.products.select("products.category", "sum(order_products.count) as count").group(:category) + @products = @user.products.select("products.*", "sum(order_items.count) as count").group(:product_id) + @categories = @user.products.select("products.category", "sum(order_items.count) as count").group(:category) end def index diff --git a/app/models/order.rb b/app/models/order.rb index 24916d3..c8199a2 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -13,27 +13,27 @@ class Order < ActiveRecord::Base include ActionView::Helpers::TextHelper after_initialize { self.total_price = 0 } - after_create { self.user.pay(price) } - before_destroy { self.user.pay(-price) } + after_create { self.user.increment!(:balance_cents, -price) } + before_destroy { self.user.increment!(:balance_cents, price) } belongs_to :user, counter_cache: true - has_many :order_products, dependent: :destroy - has_many :products, through: :order_products + has_many :order_items, dependent: :destroy + has_many :products, through: :order_items attr_accessor :total_price validates :user, presence: true - validates :order_products, presence: true, in_stock: true + validates :order_items, presence: true, in_stock: true - accepts_nested_attributes_for :order_products, reject_if: proc { |op| op[:count].to_i <= 0 } + accepts_nested_attributes_for :order_items, reject_if: proc { |oi| oi[:count].to_i <= 0 } def price - self.order_products.map{ |op| op.count * op.product.price_cents }.sum + self.order_items.map{ |oi| oi.count * oi.product.price_cents }.sum end def to_sentence - self.order_products.map { - |op| pluralize(op.count, op.product.name) + self.order_items.map { + |oi| pluralize(oi.count, oi.product.name) }.to_sentence end end diff --git a/app/models/order_product.rb b/app/models/order_item.rb similarity index 55% rename from app/models/order_product.rb rename to app/models/order_item.rb index eaa2c7d..130b736 100644 --- a/app/models/order_product.rb +++ b/app/models/order_item.rb @@ -1,22 +1,22 @@ # == Schema Information # -# Table name: order_products +# Table name: order_items # # id :integer not null, primary key -# order_id :integer -# product_id :integer -# count :integer default(1) +# order_id :integer not null +# product_id :integer not null +# count :integer default(0) # -class OrderProduct < ActiveRecord::Base - after_create :remove_from_stock - before_destroy :put_back_in_stock - +class OrderItem < ActiveRecord::Base belongs_to :order belongs_to :product validates :product, presence: true - validates :count, numericality: { greater_than_or_equal_to: 0 } + validates :count, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + + after_create :remove_from_stock + before_destroy :put_back_in_stock accepts_nested_attributes_for :product @@ -28,12 +28,10 @@ class OrderProduct < ActiveRecord::Base private def remove_from_stock - product.stock -= self.count - product.save + product.increment!(:stock, - self.count) end def put_back_in_stock - product.stock += self.count - product.save + product.increment!(:stock, self.count) end end diff --git a/app/models/product.rb b/app/models/product.rb index ae090c0..ebb4195 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -3,20 +3,20 @@ # Table name: products # # id :integer not null, primary key -# name :string(255) -# price_cents :integer -# created_at :datetime -# updated_at :datetime +# name :string(255) not null +# price_cents :integer default(0), not null +# category :integer default(0) +# stock :integer default(0), not null # avatar_file_name :string(255) # avatar_content_type :string(255) # avatar_file_size :integer # avatar_updated_at :datetime -# category :integer default(0) -# stock :integer default(0) +# created_at :datetime +# updated_at :datetime # class Product < ActiveRecord::Base - has_many :order_products + has_many :order_items has_attached_file :avatar, styles: { medium: "100x100>" }, default_style: :medium enum category: %w(food beverages other) @@ -27,12 +27,11 @@ class Product < ActiveRecord::Base validates_attachment :avatar, presence: true, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } def price - (price_cents || 0) / 100.0 + self.price_cents / 100.0 end def price=(value) if value.is_a? String then value.sub!(',', '.') end self.price_cents = (value.to_f * 100).to_int end - end diff --git a/app/models/user.rb b/app/models/user.rb index c276470..a590ba1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,8 +5,16 @@ # id :integer not null, primary key # name :string(255) # last_name :string(255) -# balance :integer default(0) +# balance_cents :integer default(0), not null # nickname :string(255) +# admin :boolean +# koelkast :boolean default(FALSE) +# dagschotel_id :integer +# orders_count :integer default(0) +# avatar_file_name :string(255) +# avatar_content_type :string(255) +# avatar_file_size :integer +# avatar_updated_at :datetime # created_at :datetime # updated_at :datetime # encrypted_password :string(255) default(""), not null @@ -16,21 +24,14 @@ # last_sign_in_at :datetime # current_sign_in_ip :string(255) # last_sign_in_ip :string(255) -# admin :boolean -# dagschotel_id :integer -# avatar_file_name :string(255) -# avatar_content_type :string(255) -# avatar_file_size :integer -# avatar_updated_at :datetime -# orders_count :integer default(0) -# koelkast :boolean default(FALSE) # class User < ActiveRecord::Base - devise :database_authenticatable, :registerable, :rememberable, :trackable + devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable + has_paper_trail only: [:balance, :admin, :orders_count, :koelkast] - has_attached_file :avatar, styles: { medium: "100x100>" }, default_style: :medium, - default_url: "http://babeholder.pixoil.com/img/70/70" + + has_attached_file :avatar, styles: { medium: "100x100>" }, default_style: :medium has_many :orders, -> { includes :products } has_many :products, through: :orders @@ -39,7 +40,6 @@ class User < ActiveRecord::Base validates :nickname, presence: true, uniqueness: true validates :name, presence: true validates :last_name, presence: true - validates :password, length: { in: 8..128 }, confirmation: true, on: :create validates_attachment :avatar, presence: true, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } scope :members, -> { where koelkast: false } @@ -48,17 +48,28 @@ class User < ActiveRecord::Base "#{name} #{last_name}" end - def pay(amount) - write_attribute(:balance, read_attribute(:balance) - amount) - self.save - end - def balance - (read_attribute(:balance) || 0) / 100.0 + self.balance_cents / 100.0 end def balance=(value) if value.is_a? String then value.sub!(',', '.') end - write_attribute(:balance, (value.to_f * 100).to_int) + self.balance_cents = (value.to_f * 100).to_int + end + + # Change URL params for User + + def to_param + "#{id} #{nickname}".parameterize + end + + # This is needed so Devise doesn't try to validate :email + + def email_required? + false + end + + def email_changed? + false end end diff --git a/app/validators/in_stock_validator.rb b/app/validators/in_stock_validator.rb index 8705fc0..8063195 100644 --- a/app/validators/in_stock_validator.rb +++ b/app/validators/in_stock_validator.rb @@ -1,7 +1,7 @@ class InStockValidator < ActiveModel::Validator def validate(record) - record.order_products.each do |op| - record.errors[op.product.name] = "is not in stock anymore" if op.count > op.product.stock + record.order_items.each do |oi| + record.errors[oi.product.name] = "is not in stock anymore" if oi.count > oi.product.stock end end end diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index f5f075b..7f01101 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -3,7 +3,6 @@
<%= f_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %> - <%= f.text_field :nickname %> <%= f.password_field :password %> diff --git a/app/views/order_items/_order_item.html.erb b/app/views/order_items/_order_item.html.erb new file mode 100644 index 0000000..12d8bfd --- /dev/null +++ b/app/views/order_items/_order_item.html.erb @@ -0,0 +1,15 @@ +
+
+
+ <%= image_tag product.avatar %> +
+ <%= content_tag :h3, "#{product.name} - #{euro(product.price)}" %> + <%= f.counter :count, skip_label: true, wrapper_class: "input-group", class: "row_counter" %> + <%= f.fields_for :product do |product| %> + <%= product.hidden_field :price_cents, class: :price %> + <%= product.hidden_field :stock, class: :stock %> + <% end %> +
+
+
+
diff --git a/app/views/order_products/_total_price.html.erb b/app/views/order_items/_total_price.html.erb similarity index 100% rename from app/views/order_products/_total_price.html.erb rename to app/views/order_items/_total_price.html.erb diff --git a/app/views/order_products/_order_product.html.erb b/app/views/order_products/_order_product.html.erb deleted file mode 100644 index 88501d2..0000000 --- a/app/views/order_products/_order_product.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -
-
-
- <%= image_tag product.avatar %> -
-

<%= product.name %> - <%= content_tag :span, euro(product.price) %>

-

- <%= f.counter :count, skip_label: true, wrapper_class: "input-group", class: "row_counter" %> - <%= f.fields_for :product do |product| %> - <%= product.hidden_field :price_cents, class: :price %> - <%= product.hidden_field :stock, class: :stock %> - <% end %> -

-
-
-
-
diff --git a/app/views/orders/_order.html.erb b/app/views/orders/_order.html.erb index 5f24f50..cdce779 100644 --- a/app/views/orders/_order.html.erb +++ b/app/views/orders/_order.html.erb @@ -1,2 +1,2 @@ <%= order.created_at %> -<%= simple_format(order.order_products.map { |p| pluralize(p.count, p.product.name) }.to_sentence) %> +<%= simple_format(order.to_sentence) %> diff --git a/app/views/orders/_overview.html.erb b/app/views/orders/_overview.html.erb index 8d390ee..da4601a 100644 --- a/app/views/orders/_overview.html.erb +++ b/app/views/orders/_overview.html.erb @@ -1,5 +1,5 @@
-

sort by name

+

Sort by name

<% users.each do |user| %> <%= render 'users/new_order', user: user %> <% end %> diff --git a/app/views/orders/new.html.erb b/app/views/orders/new.html.erb index 8fe2bf8..afde860 100644 --- a/app/views/orders/new.html.erb +++ b/app/views/orders/new.html.erb @@ -1,15 +1,15 @@

Order for <%= @user.nickname %> (<%= euro(@user.balance) %>)

- <%= form_for @order, builder: FormattedFormBuilder, url: user_orders_path(@user) do |f| %> + <%= f_form_for [@user, @order] do |f| %> <%= f.error_messages %>
- <%= f.fields_for :order_products do |op_field| %> + <%= f.fields_for :order_items do |op_field| %> <%= render op_field.object, f: op_field, product: op_field.object.product %> <% end %>
- <%= render 'order_products/total_price', f: f %> + <%= render 'order_items/total_price', f: f %> <% end %>
diff --git a/app/views/products/_form.html.erb b/app/views/products/_form.html.erb index aff0c5c..04911cd 100644 --- a/app/views/products/_form.html.erb +++ b/app/views/products/_form.html.erb @@ -1,6 +1,6 @@