ruby-on-rails - 如何使用范围作为 POST 数据到 Rails Controller 的参数之一

标签 ruby-on-rails ruby range factory-bot

数据库迁移将experience字段定义为一个范围

class CreateJobPosts < ActiveRecord::Migration[5.1]
  def change
    create_table :job_posts do |t|
      t.string :name, null: false, limit: 100
      t.string :location, null: false, limit: 100
      t.int4range :experience, null: false
      t.text :description, null: false
      t.text :skills, null:false
      t.boolean :active, null: false, default: false
      t.string :seo_meta_keywords, array: true, null: false
      t.string :seo_meta_description, null: false, limit: 150

      t.timestamps
    end
    add_index :job_posts, :name, unique: true
    add_index :job_posts, :location
    add_index :job_posts, :active
  end
end

现在在编写测试时,我让 FactoryGirl 像这样定义了一些模型

FactoryGirl.define do
    factory :job_post do
        name "DevOps Coach"
        location "Bangalore"
        experience (4..10)
        description 'Test Description'
        skills 'Test Skills'
        active true
        seo_meta_keywords ['keywords','keywords']
        seo_meta_description 'dummy descriptions'
    end
end

在 Controller 中

def job_post_params
  params.require(:job_post).permit(:name, :location, :experience, :description, :skills, :active, :seo_meta_description, seo_meta_keywords: [])
end

属性哈希按预期初始化

[89, 98] in /Users/anadi/Code/bauji/spec/controllers/job_posts_controller_spec.rb
   89:
   90:     context "with invalid params" do
   91:       it "returns a success response (i.e. to display the 'new' template)" do
   92:         byebug
   93:         temp = invalid_attributes
=> 94:         post :create, params: {job_post: invalid_attributes}, session: valid_session
   95:         expect(response).to be_success
   96:       end
   97:     end
   98:   end
(byebug) temp
{:name=>"No Name", :location=>"Nay", :experience=>4..10, :description=>"Test Description", :skills=>"Test skills", :active=>true, :seo_meta_keywords=>["keywords", "keywords"], :seo_meta_description=>"dummy descriptions"}

但是 POST 和 PUT 方法测试失败,因为 Controller 的 :experience 属性为 nil

[24, 33] in /Users/anadi/Code/bauji/app/controllers/job_posts_controller.rb
   24:   # POST /job_posts
   25:   # POST /job_posts.json
   26:   def create
   27:     byebug
   28:     @job_post = JobPost.new(job_post_params)
=> 29:     respond_to do |format|
   30:       if @job_post.save
   31:         format.html { redirect_to @job_post, notice: 'Job post was successfully created.' }
   32:         format.json { render :show, status: :created, location: @job_post }
   33:       else
(byebug) @job_post
#<JobPost:0x007fda5fb21920>
(byebug) @job_post.experience
*** ArgumentError Exception: bad value for range

nil

解决方案:

# Never trust parameters from the scary internet, only allow the white list through.
def job_post_params
  raw_post_params = params.require(:job_post).permit(:name, :location, :experience, :description, :skills, :active, :seo_meta_description, seo_meta_keywords: [])
  range_begin, range_end = raw_post_params[:experience].split('..').map { |v| Integer(v) }
  raw_post_params[:experience] = Range.new(range_begin, range_end)
  raw_post_params
end

它能更紧凑吗?

最佳答案

当您发出 POST 请求时,4..10 很可能会转换为 String:"4..10" .尝试使用类似于以下内容的内容来解析 Controller 中的字符串:

range_begin, range_end = params[:experience].split('..').map { |v| Integer(v) }
experience = Range.new(range_begin, range_end)

然后您可以将该经验设置为JobPost的属性

关于ruby-on-rails - 如何使用范围作为 POST 数据到 Rails Controller 的参数之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45255541/

相关文章:

ruby - 将 Treetop 解析树转变为抽象语法树 (AST)

r - 为什么 range() 函数比 min 和 max 的组合慢?

python - 什么是 <class 'range' >

ruby-on-rails - Rails jsonb - 当 jsonb 保存到 Postgresql 数据库时,防止 JSON 键重新排序

ruby-on-rails - 为什么 Rubymine 无法识别我的命名空间继承 Controller ?

ruby-on-rails - 从购物车中删除产品后无法将产品添加回产品模型,Ruby on rails

ruby - 要求相对路径

JavaScript - 如何用 span 标签包围 block 标签?

ruby-on-rails - 未初始化的常量 User::BCrypt(与版本有关?)

ruby-on-rails - Rails dataTables 添加行不起作用