【发布时间】:2020-01-28 21:30:25
【问题描述】:
错误:undefined method 'before_save' for YearsController:Class Did you mean? before_action
https://guides.rubyonrails.org/active_record_callbacks.html 谈到“可以创建、更新和销毁对象”,如果通过 ActiveStorage 添加的图像已经存在,我想中断该过程以避免重复。 before_save 是可用的回调之一。
导轨 (6.0.0)。我对 ActiveRecord 回调没有经验,但 https://api.rubyonrails.org Active Record 回调列出了 before_save,但不是 before_action。但是before_action. 没有错误我什至不确定何时需要激活回调,但我正在努力解决问题。允许哪些回调?并且不确定before_action 会是什么。
years_controller.rb
class YearsController < ApplicationController
helper_method :sort_column, :sort_direction
before_action :set_year, only: [:show, :edit, :update, :destroy] # 2019.06.20 Can't see that this is being used anywhere
before_action :set_s3_direct_post, only: [:new, :edit, :create, :update]
# before_action :dup_check, only: [:new, :edit, :update] # runs, but not what I think I want
before_save :dup_check, only: [:new, :edit, :update] # undefined method `before_save' for YearsController:Class Did you mean? before_action
PAGE_SIZE = 10
def index
@years = Year.order(sort_column + " " + sort_direction)
respond_to do |format|
format.html {}
format.json { render json: @years }
end
end
def documents
@years = Year.all
end
def map_one # mapping one connection/year
# need to use the year passed in and then make it for a year
years = Year.where( year_date: '1865-01-01' .. '1995-12-31' )
end
def search
# Copeland except within the else
@page = (params[:page] || 0).to_i
if params[:keywords].present?
@keywords = params[:keywords]
year_search_term = YearSearchTerm.new(@keywords)
@years = Year.where(
year_search_term.where_clause,
year_search_term.where_args).
order(year_search_term.order).
offset(PAGE_SIZE * @page).limit(PAGE_SIZE)
else
@years = Year.order(sort_column + " " + sort_direction)
end
respond_to do |format|
format.html {}
format.json { render json: @years }
end
end
def summary
@years = Year.order(:year_date)
respond_to do |format|
format.html {}
format.json { render json: @years }
end
end
def show
end
# GET /years/new
def new
# All from Tutorial Points Tutorial
@year = Year.new({:year_date => "1900-09-01"}) # This is default. Helps to change when going through a group.
@locations = Location.all
@people = Person.all
end
# GET /years/1/edit
def edit
@positions = Position.all # Needed for Positions/ Titles list to work, However not added to database
end
# POST /years
# POST /years.json
def create
@year = Year.new(year_params)
respond_to do |format|
if @year.save
format.html { redirect_to @year, notice: 'Connection was successfully created.' }
format.json { render :show, status: :created, location: @year }
else
format.html { render :new }
format.json { render json: @year.errors, status: :unprocessable_entity }
end
end
repopulateResidResto()
end
# PATCH/PUT /years/1
# PATCH/PUT /years/1.json
def update
respond_to do |format|
if @year.update(year_params)
format.html { redirect_to @year, notice: 'Connection was successfully updated.' }
format.json { render :show, status: :ok, location: @year }
else
format.html { render :edit }
format.json { render json: @year.errors, status: :unprocessable_entity }
end
end
repopulateResidResto() # nice to have some error handling here
end
# DELETE /years/1
# DELETE /years/1.json
def destroy
@year.destroy
respond_to do |format|
format.html { redirect_to years_url, notice: 'Connection was successfully destroyed.' }
format.json { head :no_content }
end
repopulateResidResto()
end
private
# Use callbacks to share common setup or constraints between actions.
def set_year
@year = Year.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def year_params
params.require(:year).permit(:year_date, :person_id, :location_id, :resto, :resto_name, :resid, :title, :source, :source_url, :ref_image, :doc_image , :ref_url, :notes, :ref_url, :caption, documents: []) # document replaces _images, brackets for has many
end
def set_s3_direct_post
@s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: '201', acl: 'public-read')
end
def dup_check
# if active_storage_blobs(:checksum ) == an existing blob
# let's first run a test seeing if a know checksum exists. That works. Now get the existing checksums
test_checksum = '0M4nc4nuUaVuqo3+sJw+Lg==' # will get for selected image at some point
test_checksum == '0M4nc4nuUaVuqo3+sJw+Lg==' ? (puts "years_controller:158. test_checksum #{test_checksum} does exist") : (puts "years_controller:158. test_checksum #{test_checksum} does not exist") # Need the ()
puts "years_controller:160. dup_check entered via before_action. before_save results in an errro"
end
# NOT CLEAR ANY OF THIS IS NEEDED. BUT PUT IT IN AGAIN WHEN CREATE DIDN'T WORK
def person_params
params.require(:person).permit(:last_name, :given_name, :full_name, :full_name_id)
end
def sort_column
Year.column_names.include?(params[:sort]) ? params[:sort] : "year_date" # it does matter what this last field is.
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
end
year.rb
class Year < ApplicationRecord
belongs_to :location
belongs_to :person
has_many :resto_resid_lines
has_many_attached :documents # ActiveStorage
has_rich_text :caption # ActionText 2019.12.05 not implemented because form needs major changes to work
scope :with_eager_loaded_documents, -> { eager_load(documents_attachments: :blob) }
default_scope -> { order(:year_date) }
validates :person_id, presence: true
validates :location_id, presence: true
validates_presence_of :resto, {:if => :resto_name?, message: 'Click on Restaurant (above) since a restaurant name has been selected' }
validates :resto, :presence => { :if => :resto_name?, message: 'Select Restaurant since a restaurant name has been specified' } # is this the same as above, but not working?
def self.search(search)
where("year_date ILIKE ? OR resto ILIKE ? OR resto_name ILIKE ? OR resid ILIKE ? OR title ILIKE ? OR source ILIKE ? OR source_url ILIKE ? OR ref_url ILIKE ? OR notes ?", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%")
end
def map_popup
"#{person.given_name} #{person.last_name} was a #{title} at #{location.address} in #{year_date.to_formatted_s(:month_year)}"
end
def next
Year.where("id > ? AND year_date = ?", id, year_date).first
end
def previous
Year.where("id < ? AND year_date = ?", id, year_date).last
end
private
def resid_xor_resid
if [resto, resid].compact.count != 1
errors.add(:base, "Select Residence or Restaurant, but not both")
end
end
end
很多麻烦,因为这是我的第一个应用程序,我已经为此工作多年。
【问题讨论】:
-
before_save是模型级别,before_action是控制器级别。可以发YearsController和year模特吗? -
@7urkm3n 完成。感谢收看。
-
它看起来对我来说很好,什么时候发生?
-
@7urkm3n。我意识到我需要消化你说的话。这是我想要的控制器动作。所以我需要弄清楚这一点。谢谢。
-
@7urkm3n 谢谢你的建议。我需要自己尝试一下并对文档进行一些研究。可能最终会出现在新帖子中。
标签: ruby-on-rails activerecord callback ruby-on-rails-6 before-save