after_validation:set_full_name在Ruby on Rails

时间:2018-10-06 23:08:36

标签: ruby-on-rails

问题:

我正在制作一个老年护理应用程序。我有两个模型RoomArea。我已经在房间表上创建了一个名为full_name的列。验证之后,我想保存全名。这将用作友好标签显示

我将在常驻表格上使用它

  <div class="col-md-4">
    <%= f.association :room, collection: @current_business.rooms.order(:name).pluck(:full_name, :id), prompt: "Choose a room"   %>
  </div>

我尝试过的事情:

我已经阅读了很多堆栈文章。我已经阅读了ruby文档。我只是一个初级开发人员,我被困住了,请帮忙!

我认为问题出在这部分:

 def set_full_name
    if @room.name.changed? || @area.name_changed?
      self.full_name = [@room.name, @area.name].select(&:present?).join(' ').titleize
    end
  end

Room.rb

# == Schema Information
#
# Table name: rooms
#
#  id          :bigint(8)        not null, primary key
#  name        :string
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#  area_id     :bigint(8)
#  business_id :integer
#  author_id   :integer
#  deleted_at  :datetime
#  full_name   :string
#

class Room < ApplicationRecord
  acts_as_paranoid

  after_validation :set_full_name

  validates :name, presence: true, length: { maximum: 50 }
  belongs_to :area
  has_many :residents

  def set_full_name
    if @room.name.changed? || @area.name_changed?
      self.full_name = [@room.name, @area.name].select(&:present?).join(' ').titleize
    end
  end

end

Area.rb

# == Schema Information
#
# Table name: areas
#
#  id          :bigint(8)        not null, primary key
#  name        :string
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#  location_id :bigint(8)
#  business_id :integer
#  author_id   :integer
#  deleted_at  :datetime
#

class Area < ApplicationRecord
  acts_as_paranoid
  belongs_to :location
  belongs_to :business
  validates :name, presence: true, length: { maximum: 100 }

  has_many :rooms, -> { order(id: :asc) }, inverse_of: :area
  accepts_nested_attributes_for :rooms, reject_if: :all_blank, allow_destroy: true



end

Rooms_controller

class App::RoomsController < App::BaseController
  before_action :set_room, only: [:show, :edit, :update, :destroy]

  # GET /rooms
  # GET /rooms.json
  def index
    @rooms = current_business.rooms.order(name: :asc).paginate(:page => params[:page])
  end

  # GET /rooms/1
  # GET /rooms/1.json
  def show
  end

  # GET /rooms/new
  def new
    @room = current_business.rooms.new
  end

  # GET /rooms/1/edit
  def edit
  end

  # POST /rooms
  # POST /rooms.json
  def create
    @room = current_business.rooms.new(room_params)
    @room.author_id = current_user.id

    respond_to do |format|
      if @room.save
        format.html { redirect_to app_room_path(@room), notice: 'Room was successfully created.' }
        format.json { render :show, status: :created, location: @room }
      else
        format.html { render :new }
        format.json { render json: @room.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /rooms/1
  # PATCH/PUT /rooms/1.json
  def update
    @room.author_id = current_user.id

    respond_to do |format|
      if @room.update(room_params)
        format.html { redirect_to app_room_path(@room), notice: 'Room was successfully updated.' }
        format.json { render :show, status: :ok, location: @room }
      else
        format.html { render :edit }
        format.json { render json: @room.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /rooms/1
  # DELETE /rooms/1.json
  def destroy
    @room.destroy
    respond_to do |format|
      format.html { redirect_to app_rooms_path, notice: 'Room was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_room
      @room = current_business.rooms.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def room_params
      params.require(:room).permit(:name, :area_id, :deleted_at, :business_id, :author_id, :business_id, :author_id, :full_name)
    end
end

2 个答案:

答案 0 :(得分:1)

为什么不仅仅使用full_name方法。像这样:

class Room < ApplicationRecord
  acts_as_paranoid

  validates :name, presence: true, length: { maximum: 50 }
  belongs_to :area
  has_many :residents

  def full_name
    "#{name} #{area.name}".titleize
  end

end

您已经在nameRoom上都验证了Area,那么为什么.select(&:present?)等所有业务都如此?只需使用字符串插值然后进行标题即可。

这样,全名将始终基于当前值,而无需使用after_validation进行“刷新”等等。

答案 1 :(得分:0)

我找到了另一种解决方案

  def set_full_name
    self.full_name = self.name
    self.full_name += ', ' + self.area.name if self.area
  end