Reputation: 4087
SO I have this app, that let's users order shirt online.
This is how the item order looks, it has shirt size, shirt color, phone number, address, and order status.
I was modifying the existing code so that the admin users can change the order status from "ordered" into "processing", or "delivered" by selecting an option from a dropdown list below the order status.
Right now I'm not sure if I'm doing it right. It's giving me an error when I click on the update link, and it's highlighting a code in my controller
SO this is my Model
class Micropost < ApplicationRecord
belongs_to :user
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :shirtSize, presence: true
validates :shirtColor, presence: true
validates :contactAddress, presence: true
validates :contactNumber, presence: true
validate :picture_size
#uncomment picture presence validation in the future
# validates :picture, presence: true
SIZE_LIST = [ " ", "S", "M", "L", "XL" ]
COLOR_LIST = [ " ", "Black", "White", "Gray", "Red", "Green", "Blue", "Navy Blue", "Yellow", "Pink"]
STATUS_LIST = [ "Ordered", "Processing", "Delivered"]
private
# Validates the size of an uploaded picture.
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
VIEW
<li id="micropost-<%= micropost.id %>">
<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
<span class="user"><%= link_to micropost.user.name, micropost.user %>
</span>
<span class="content">
<%= "#{micropost.shirtSize}, #{micropost.shirtColor}" %>
<% if current_user?(micropost.user) || current_user.admin? %><br/>
<%= "#{micropost.contactNumber} | #{micropost.contactAddress}" %>
<br/>
<h4>Status: <%= micropost.orderStatus %></h4>
<% end %>
//dropdown list for changing order status that is only available for admin users
<% if current_user.admin? %><br/>
<%= form_for(@micropost) do |f| %>
<div class="field">
<%= f.select :orderStatus, Micropost::STATUS_LIST %>
<%= link_to "Update", micropost, method: :patch %>
</div>
<% end %>
<% end %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
<% if current_user?(micropost.user) && micropost.orderStatus == "Ordered" %>
<%= link_to "Cancel", micropost, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<span class="content">
<%= image_tag micropost.picture.url if micropost.picture? %>
</span>
</li>
CONTROLLER
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy, :update]
before_action :correct_user, only: :destroy
before_action :admin_user, only: :update
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Design Posted!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
def destroy
@micropost.destroy
flash[:success] = "Design deleted"
redirect_to request.referrer || root_url
end
def update
@micropost = Micropost.find(params[:id])
if @micropost.update(update_micropost_params)
flash[:success] = "Micropost updated"
redirect_to @micropost
else
flash[:error] = 'There was a problem updating this micropost'
render :edit
end
end
private
def micropost_params
defaults = { orderStatus: 'Ordered' }
params.require(:micropost).permit(:shirtSize, :shirtColor, :contactNumber, :contactAddress, :picture).merge(defaults)
end
def update_micropost_params
params.require(:micropost).permit(:shirtSize, :shirtColor, :contactNumber, :contactAddress, :picture, :orderStatus)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if @micropost.nil?
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
ROUTES
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users do
member do
get :following, :followers
end
end
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :microposts, only: [:create, :destroy, :update]
resources :relationships, only: [:create, :destroy]
end
Upvotes: 2
Views: 300
Reputation: 4087
I figured it out, I changed the update method in my controller
def update
@micropost = Micropost.find(params[:id])
status = 'Ordered'
if @micropost.orderStatus == 'Ordered'
status = 'Processing'
elsif @micropost.orderStatus == 'Processing'
status = 'Delivered'
end
@micropost.update_attributes(orderStatus: status)
if @micropost.save
flash[:notice] = "Entry was successfully updated"
redirect_to request.referrer || root_url
else
flash[:error] = 'There was a problem updating this micropost'
redirect_to request.referrer || root_url
end
end
I also updated my view into something like this:
<li id="micropost-<%= micropost.id %>">
<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
<span class="user"><%= link_to micropost.user.name, micropost.user %></span>
<span class="content">
<%= "#{micropost.shirtSize}, #{micropost.shirtColor}" %>
<% if current_user?(micropost.user) || current_user.admin? %><br/>
<%= "#{micropost.contactNumber} | #{micropost.contactAddress}" %><br/>
<h4>Status: <%= micropost.orderStatus %></h4>
<% end %>
<% if current_user.admin? %>
<%= link_to "Update", micropost, method: :patch %>
<% end %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
<% if current_user?(micropost.user) && micropost.orderStatus == "Ordered" %>
<%= link_to "Delete", micropost, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<span class="content">
<%= image_tag micropost.picture.url if micropost.picture? %>
</span>
Upvotes: 2
Reputation: 5972
Reading the comments on this file will show you what is generated by the scaffold generator. This can be thought of as default controller implementation, which includes an update method.
Upvotes: 0
Reputation: 2222
Normally, for an update action, you would do something like this:
def update
if admin_user
@micropost = Microposts.find(params[:id]) # you may need to adjust this if your route is nested
if @micropost.update(micropost_params)
flash[:success] = "Micropost updated"
redirect_to @micropost
else
flash[:error] = 'There was a problem updating this micropost'
render :edit
end
end
end
This will probably have to be adjusted since you are using an admin user to make the update.
Upvotes: 1