Rails 3.1 Web 服务的数据类型未正确传递

发布于 2024-12-21 13:35:19 字数 758 浏览 3 评论 0原文

我有一个 Rails RESTful Web 服务应用程序,它接受来自客户端的值以增加数据库中的值。数据库值是一个整数,但是当使用 rspec 测试代码时,传入的值被解释为字符串。

我正在使用 Rails 3.1 和 Ruby 1.9.2。

这是 rspec 片段:

...
it "should find Points and return object" do
  put :update, :username => "tester", :newpoints => [10, 15, 0], :format => :xml
end
...

这是控制器代码:

...
respond_to do |format|
  if points.update_attributes([xp + :newpoints[0]][sp + :newpoints[1]][cash +        :newpoints[2]])
    format.json { head :ok }
    format.xml { head :ok }
...

xp、sp 和 cash 是来自数据库的值,并且已被验证为 Fixnum 数据类型。我收到的错误是:

TypeError: String can't be coerced into Fixnum

如何编写测试以确保传递的参数作为正确的数据类型传递?

如果需要,我可以包含更多代码。提前致谢!

I have a Rails RESTful web service application that accepts a value from a client to increment the value in the database. The database value is an integer, but when using rspec to test the code, the value being passed in is interpreted as a string.

I'm using Rails 3.1 and Ruby 1.9.2.

Here's the rspec snippet:

...
it "should find Points and return object" do
  put :update, :username => "tester", :newpoints => [10, 15, 0], :format => :xml
end
...

Here's the controller code:

...
respond_to do |format|
  if points.update_attributes([xp + :newpoints[0]][sp + :newpoints[1]][cash +        :newpoints[2]])
    format.json { head :ok }
    format.xml { head :ok }
...

xp, sp and cash are values from the database and have been validated as Fixnum datatype. The error I am getting is:

TypeError: String can't be coerced into Fixnum

How do I write my test to ensure that the parameters being passed are passed as the proper datatype?

I can include more of the code if needed. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱娆 2024-12-28 13:35:19

我花了一番心思,但我发现我传递的所有内容都是错误的。我提出的解决方案绝对不是最好的解决方案,可能可以重写,但它有效,目前就足够了。

对 rspec 片段的更改是创建由符号 :newpoints 表示的散列

it "should find Points and return object" do
  put :update, :username => "tester", :newpoints => {"experience_points" => 10, "shame_points" => 15, "gold" => 0}, :format => :xml
end

在控制器中处理此请求需要进行一些调整,但以下是相关部分:

class PointsController < ApplicationController
  #before_filter :authenticate, :only => :update
  before_filter :must_specify_user
  before_filter :fix_params
  before_filter :clean_up
  respond_to :html, :xml, :json

  def fix_params
    if params[:points]
      params[:points][:user_id] = @user.id if @user
    end
  end

 def clean_up
   @newpoints = params[:newpoints]
   @experience = @newpoints["experience_points"]
   @shame = @newpoints["shame_points"]
   @gold = @newpoints["gold"]
   @xp = @experience.to_i
   @sp = @shame.to_i
   @cash = @gold.to_i
end

def update
  points = Points.find_by_user_id(@user.id, params[:id])
  xp = points.experience_points
  sp = points.shame_points
  cash = points.gold
  final_experience = xp += @xp
  final_shame = sp += @sp
  final_gold = cash += @cash
  final_points = {:experience_points => final_experience, :shame_points => final_shame, :gold => final_gold}
  if_found points do
    respond_to do |format|
      if points.update_attributes!(params[final_points])
        format.json { head :ok }
        format.xml { head :ok }
      else
        format.json { render :nothing => true, :status => "401 Not Authorized"}
        format.xml { render :nothing => true, :status => "401 Not Authorized"}
      end
    end
  end
end
end

显然,可以做很多事情来使其遵循 DRY 以及其他方法,所以仍然欢迎任何建议。提前致谢!

It took me a bit of head banging, but I found out that I was passing everything in wrong. The solution I've come up with is definitely not the best solution and could probably be re-written, but it works and for now, that's sufficient.

The change to the rspec snippet was to create hash represented by symbol :newpoints

it "should find Points and return object" do
  put :update, :username => "tester", :newpoints => {"experience_points" => 10, "shame_points" => 15, "gold" => 0}, :format => :xml
end

The handling of this request in the controller required a bit of tweaking, but here's the pertinent pieces:

class PointsController < ApplicationController
  #before_filter :authenticate, :only => :update
  before_filter :must_specify_user
  before_filter :fix_params
  before_filter :clean_up
  respond_to :html, :xml, :json

  def fix_params
    if params[:points]
      params[:points][:user_id] = @user.id if @user
    end
  end

 def clean_up
   @newpoints = params[:newpoints]
   @experience = @newpoints["experience_points"]
   @shame = @newpoints["shame_points"]
   @gold = @newpoints["gold"]
   @xp = @experience.to_i
   @sp = @shame.to_i
   @cash = @gold.to_i
end

def update
  points = Points.find_by_user_id(@user.id, params[:id])
  xp = points.experience_points
  sp = points.shame_points
  cash = points.gold
  final_experience = xp += @xp
  final_shame = sp += @sp
  final_gold = cash += @cash
  final_points = {:experience_points => final_experience, :shame_points => final_shame, :gold => final_gold}
  if_found points do
    respond_to do |format|
      if points.update_attributes!(params[final_points])
        format.json { head :ok }
        format.xml { head :ok }
      else
        format.json { render :nothing => true, :status => "401 Not Authorized"}
        format.xml { render :nothing => true, :status => "401 Not Authorized"}
      end
    end
  end
end
end

Obviously, much can be done to make this follow DRY and what not, so any suggestions are still welcome. Thanks in advance!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文