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
我有我的 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