在我的“入门”模式中......
class Entry < ActiveRecord::Base
...我试图将属性的值直接传递给下面的数据验证(动态更新的属性是':wpu',值是基于用户表单提交的整数。有三个用户从下拉菜单中选项将提交':wpu'的值;为了进行此对话,请考虑“5”,“10”或“20”的值。
validates :text, length: { is: DYNAMIC_VALUE_WOULD_GO_HERE,
tokenizer: lambda { |str| str.squish.gsub('&'){''}.scan(/\w+/) }
}
当字符串属性的字数':text'等于前面提到的另一个属性':wpu'的整数时,这将验证。如果我用'5','10'或'20'替换'DYNAMIC_VALUE_WOULD_GO_HERE',上面的代码是完美的,但我没有成功根据用户的输入在那里放置动态值。
我已经做了这件事 - 可能有一个简单的答案 - 现在已经3天了,但没有成功。
我尝试过的事情:
1)使用attr_reader并调用属性值 2)将控制器方法参数传递给模型
我对任何建议和其他方法持开放态度。我是红宝石和铁轨的初学者。
这是我的完整型号代码。它目前不起作用,因为我无法通过'params'。否则,如果我删除下面的随机实验方法,不试图使这个动态,一切正常。
class Entry < ActiveRecord::Base
belongs_to :story
attr_reader :wpu
#method used to generate 'wpu' | which is words per user in Story
def self.storywpu
#story ID from EntriesController
current_entry_story_id = Entry.find(params[:id]).story_id
#returns 'wpu' | which is words per user in Story
storywpu = Story.find(current_entry_story_id).wpu
return storywpu
end
#strips ALL white space before form submission
auto_strip_attributes :text, :nullify => false, :squish => true
#validates each field has been filled out
validates :user_id, presence: true
validates :story_id, presence: true
validates :text, presence: true, autocomplete: false
#validates word count is exactly 'wpu' | which is words per user in Story
validates :text, length: { is: self.storywpu,
tokenizer: lambda { |str| str.squish.gsub('&'){''}.scan(/\w+/) }
}
end
这是我的控制器的一个相关部分供参考......
class EntriesController < ApplicationController
before_action :set_entry, only: [:show, :edit, :update, :destroy]
def create
#New text entry
@entry = Entry.create(entry_params)
#Related story params
@story = Story.find(@entry.story_id)
@storyWPU = Story.find(@entry.story_id).wpu
@word_count = @entry.text.squish.gsub('&'){''}.scan(/\w+/).size.to_i
@wordsLeft = @storyWPU - @word_count
if @word_count.nil?
@response = 'enter ' + @wordsLeft.to_s + ' words'
elsif @wordsLeft == 1
@response = 'enter ' + @wordsLeft.to_s + ' word'
elsif @wordsLeft < 0
@response = @wordsLeft.abs.to_s + ' too many!'
else
@response = 'enter ' + @wordsLeft.to_s + ' words'
end
respond_to do |format|
if @entry.save
format.html { redirect_to edit_story_path(@story), notice: 'Nice!' }
format.json { render :show, status: :created, location: @entry }
else
format.html { redirect_to edit_story_path(@story), notice: @response }
format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end
private
def set_entry
@entry = Entry.find(params[:id])
end
private
def entry_params
params.require(:entry).permit(:text, :user_id, :story_id, :wpu)
end
end
答案 0 :(得分:0)
我认为这一切都错了。我通过将动态验证虚拟地移动到控制器中来解决这个问题。基本上,如果在文本字段中提交的单词数量与属性值之一不匹配,我试图避免保存到数据库。
现在一切正常。这是我的控制器&#39;创建&#39;代码供参考......
def create
#New entry
@entry = Entry.new(entry_params)
#story variables
@story = Story.find(@entry.story_id)
@storyWPU = Story.find(@entry.story_id).wpu
@word_count = @entry.text.squish.gsub('&'){''}.scan(/\w+/).size.to_i
@wordsLeft = @storyWPU - @word_count
if @word_count.nil?
@response = 'enter ' + @wordsLeft.to_s + ' words'
elsif @wordsLeft == 1
@response = 'enter ' + @wordsLeft.to_s + ' word'
elsif @wordsLeft < 0
@response = @wordsLeft.abs.to_s + ' too many!'
else
@response = 'enter ' + @wordsLeft.to_s + ' words'
end
respond_to do |format|
if @wordsLeft == 0 && @entry.save
format.html { redirect_to edit_story_path(@story), notice: 'Nice!' }
format.json { render :show, status: :created, location: @entry }
else
format.html { redirect_to edit_story_path(@story), notice: @response }
format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end