如何在Rails中更新模型属性

时间:2019-05-04 08:39:05

标签: ruby-on-rails railstutorial.org

我有这个应用程序,可以让用户在线订购衬衫。

这是订单的外观,它具有衬衫尺寸,衬衫颜色,电话号码,地址和订单状态。

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

查看

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

控制器

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 个答案:

答案 0 :(得分:2)

我知道了,我更改了控制器中的更新方法

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 :(得分:1)

通常,对于更新操作,您将执行以下操作:

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

由于您使用管理员用户进行更新,因此可能必须对此进行调整。

答案 2 :(得分:0)

阅读this file上的注释将向您展示支架生成器生成的内容。可以将其视为默认的控制器实现,其中包括更新方法。