Rails - 如果字段具有特定值,则不允许更新模型

Rails - not letting model be updated if fields have certain values

我有我的 Ticket 模型。除了其他字段外,我还有两个 select 字段。现在,在我的创建操作中,我有这个:

if @ticket.user_id != 0 && @ticket.team_id != 0
  flash[:alert] = "You cannot assign a ticket to both a team and a user!"
  render action: "new"
else
  .... *execute update code normally*
end

因为我不能让它们都与 0 不同,这很有效。

但是我的更新操作中有相同的行,它仍然允许两个字段都不同于 0。

知道为什么吗?或者您有其他更好的处理方法吗?

这是我的控制器:

class TicketsController < ApplicationController
  before_filter :authenticate_user!
  def show
    @ticket = Ticket.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @ticket }
    end
  end
  def new
    @ticket = Ticket.new
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @ticket }
    end
  end
  def edit
    @ticket = Ticket.find(params[:id])
    @ticket.content = nil
    @ticket.whodidit = current_user.id
  end
  def create
    @ticket = Ticket.new(params[:ticket])
    @ticket.whodidit = current_user.id
    if @ticket.user_id != 0 && @ticket.team_id != 0
      flash[:alert] = "You cannot assign a ticket to both a team and a user!"
      render action: "new"
    else
    respond_to do |format|
      if @ticket.save
        TicketMailer.ticket_creation(@ticket).deliver
        format.html { redirect_to @ticket, notice: 'Ticket was successfully created.' }
        format.json { render json: @ticket, status: :created, location: @ticket }
      else
        format.html { render action: "new" }
        format.json { render json: @ticket.errors, status: :unprocessable_entity }
      end
    end
    end
  end
  def update
    @ticket = Ticket.find(params[:id])
    if (params[:user_id] != 0 && params[:team_id] != 0)
       flash[:alert] = "You cannot assign a ticket to both a team and a user!"
       render action: "edit"
    else
    respond_to do |format|
      if @ticket.update_attributes(params[:ticket])
        TicketMailer.ticket_update(@ticket).deliver
        format.html { redirect_to @ticket, notice: 'Ticket was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @ticket.errors, status: :unprocessable_entity }
      end
    end
    end
  end
  def destroy
    @ticket = Ticket.find(params[:id])
    @ticket.destroy
    respond_to do |format|
      format.html { redirect_to tickets_url }
      format.json { head :no_content }
    end
  end
  def index
    @tickets = Ticket.paginate :page => params[:page], :per_page => 10, :order => 'id DESC'
  end
end

这是我的模型:

class Ticket < ActiveRecord::Base
  belongs_to :department
  belongs_to :user
  belongs_to :team
  has_many :comments
  has_paper_trail
  attr_accessible :attachment, :subject, :content, :user_id, :department_id, :status, :priority, :shop_id, :order_id, :team_id, :whodunnit
  has_attached_file :attachment
  validates_attachment_content_type :attachment, {:content_type => %w(image/jpeg image/jpg image/png application/pdf application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document)}
  def self.receive_mail(message)
   id = message.subject[/(\d+)$/, 1]
   if id.present? && Ticket.exists?(id)
     Ticket.update(id, content: message.body.decoded, user_id:11)
   else
     Ticket.create subject: message.subject, content: message.body.decoded, department_id: 2, :incoming_email => message.from.first
   end
 end
end

您需要向我们展示您的控制器才能完整回答该问题。但是我会说这种逻辑是特定于模型的,与控制器无关。您需要将该逻辑移动到模型中的验证器方法中。如果模型在保存时无效 (create/update),那么问题无论如何都会在您的控制器中出现。请 post 你的模型和控制器脚本,这样我就可以向你展示修改它们以获得你想要的东西的最佳方法。当你这样做时,我会更新我的答案。

编辑:

可以这么说,拒绝保存的逻辑已移入模型并与 activerecord 验证一起使用。现在,无论您是在创建还是在更新,当实例尝试保存时,相同的逻辑将是 运行。

您的Class定义:

class Ticket < ActiveRecord::Base
  belongs_to :department
  belongs_to :user
  belongs_to :team
  has_many :comments
  has_paper_trail
  attr_accessible :attachment, :subject, :content, :user_id, :department_id, :status, :priority, :shop_id, :order_id, :team_id, :whodunnit
  has_attached_file :attachment
  validates_attachment_content_type :attachment, {:content_type => %w(image/jpeg image/jpg image/png application/pdf application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document)}
  validate :check_ticket

  def self.receive_mail(message)
    id = message.subject[/(\d+)$/, 1]
    if id.present? && Ticket.exists?(id)
      Ticket.update(id, content: message.body.decoded, user_id:11)
    else
      Ticket.create subject: message.subject, content: message.body.decoded, department_id: 2, :incoming_email => message.from.first
    end
  end

private

  def check_ticket
    # The logic here is semantically confusing for me, as to why user_id and team_id being 0 means that you've assigned a ticket to both team and user, but I'm sure you have your reasons.
    user_id != 0 && team_id != 0 and errors.add(:base, 'You cannot assign a ticket to both a team and a user!')
  end
end

您的控制器:

class TicketsController < ApplicationController
  ...
  def create
    @ticket = Ticket.new(params[:ticket])
    @ticket.whodidit = current_user.id

    respond_to do |format|
      if @ticket.save
        TicketMailer.ticket_creation(@ticket).deliver
        format.html { redirect_to @ticket, notice: 'Ticket was successfully created.' }
        format.json { render json: @ticket, status: :created, location: @ticket }
      else
        format.html { render action: "new" }
        format.json { render json: @ticket.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    @ticket = Ticket.find(params[:id])
    respond_to do |format|
      if @ticket.update_attributes(params[:ticket])
        TicketMailer.ticket_update(@ticket).deliver
        format.html { redirect_to @ticket, notice: 'Ticket was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @ticket.errors, status: :unprocessable_entity }
      end
    end
  end
  ...
end