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

时间:2015-01-01 15:31:22

标签: ruby-on-rails ruby ruby-on-rails-3

我有我的Ticket模型。除了其他字段,我还有两个选择字段。现在,在我的Create操作中,我有这个:

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,这很有效。

但是我的Update操作中有相同的行,并且它仍然允许两个字段不同于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

1 个答案:

答案 0 :(得分:1)

您需要向我们展示您的控制器才能完全回答这个问题。但是我会说这种逻辑是特定于模型的,与控制器没什么关系。您需要将该逻辑移动到模型中的验证器方法中。如果在保存(创建/更新)时模型无效,那么无论如何问题都会冒泡进入您的控制器。请发布您的模型和控制器脚本,以便我向您展示修改它们以获得您想要的最佳方式。当你这样做时,我会更新我的答案。

编辑:

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

您的班级定义:

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