Как обновить атрибут Model в Rails - PullRequest
2 голосов
/ 04 мая 2019

ТАК У меня есть это приложение, которое позволяет пользователям заказывать футболки онлайн.

Так выглядит заказ товара: размер рубашки, цвет рубашки, номер телефона, адрес и статус заказа.

enter image description here

Я модифицировал существующий код, чтобы пользователи-администраторы могли изменить статус заказа с «заказано» на «обработано» или «доставлено», выбрав опцию в раскрывающемся списке под статусом заказа.

Прямо сейчас я не уверен, правильно ли я делаю. Выдает ошибку при нажатии на ссылку обновления и подсвечивает код в моем контроллере

enter image description here

ТАК это моя модель

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

МАРШРУТЫ

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

Ответы [ 3 ]

2 голосов
/ 06 мая 2019

Я понял это, я изменил метод обновления в моем контроллере

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

Я также обновил мой взгляд примерно так:

<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>

1 голос
/ 04 мая 2019

Обычно для действия обновления вы должны сделать что-то вроде этого:

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

Это, вероятно, придется изменить, так как вы используете администратора для создания обновления.

0 голосов
/ 04 мая 2019

Читая комментарии к этот файл покажет вам, что генерируется генератором скаффолдов.Это можно рассматривать как реализацию контроллера по умолчанию, которая включает метод обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...