【问题标题】:Rails 4: Pass attribute's value into the model for dynamic vailidationRails 4:将属性的值传递给模型以进行动态验证
【发布时间】:2016-07-10 13:23:19
【问题描述】:

在我的“入门”模型中...

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' 的整数。如果我将 'DYNAMIC_VALUE_WOULD_GO_HERE' 替换为 '5'、'10' 或 '20',上面的代码可以完美运行,但我没有成功根据用户的输入在其中放置动态值。

我已经在这件事上工作了 3 天——可能有一个简单的答案——但没有成功。

我尝试过的事情:

1) 使用 attr_reader 并调用属性值 2) 将控制器方法参数传递给模型

我愿意接受任何建议和其他方法。我是 ruby​​ 和 rails 的初学者。

这是我的完整模型代码。它目前不起作用,因为我无法通过“参数”。否则,如果不尝试使这种动态化,如果我删除下面的随机实验方法,一切都会正常。

    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

【问题讨论】:

    标签: ruby-on-rails validation model controller attributes


    【解决方案1】:

    我做错了。我通过将动态验证虚拟移动到控制器中解决了这个问题。基本上,如果文本字段中提交的单词数量与属性值之一不匹配,我会尽量避免保存到数据库中。

    现在一切正常。这是我的控制器“创建”代码供参考...

    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
    

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      相关资源
      最近更新 更多