gpt4 book ai didi

ruby - 为 Sinatra 生成 JSON

转载 作者:数据小太阳 更新时间:2023-10-29 07:32:43 26 4
gpt4 key购买 nike

我在将生成的对象的 JSON 表示法传递到我的 Sinatra 应用程序时遇到了问题。我的问题是双重的:

  • 我有 2 个使用 Sequel gem 映射到数据库的类。当他们生成 JSON 时,它就可以并正确实现。
  • 我有一个名为 registration 的自定义类,它将其中一个类映射到一个附加字段。目标是从中生成 JSON 并将该 JSON 传递给使用 Cucumber 的应用程序(测试目的)

负责处理请求的应用程序代码定义了以下函数:

post '/users' do
begin
hash = JSON.parse(self.request.body.read)
registration = Registration.new.from_json(@request.body.read)
registration.user.country = Database::Alaplaya.get_country_by_iso_code(registration.user.country.iso_code)
return 400 unless(registration.is_valid?)
id = Database::Alaplaya.create_user(registration.user)

# If the registration failed in our system, return a page 400.
return 400 if id < 1
end
  • 问题 1:我无法使用参数散列。它存在但只是一个空哈希。为什么?
  • 问题 2:我无法反序列化类本身生成的 JSON。为什么?

注册类如下所示:

require 'json'

class Registration
attr_accessor :user, :project_id

def to_json(*a)
{
'json_class' => self.class.name,
'data' => [@user.to_json(*a), @project_id]
}.to_json(*a)
end

def self.json_create(o)
new(*o['data'])
end

# Creates a new instance of the class using the information provided in the
# hash. If a field is missing in the hash, nil will be assigned to that field
# instead.
def initialize(params = {})
@user = params[:user]
@project_id = params[:project_id]
end

# Returns a string representing the entire Registration.
def inspect
"#{@user.inspect} - #{@user.country.inspect} - #{@project_id}"
end

# Returns a boolean valid representing whether the Registration instance is
# considered valid for the API or not. True if the instance is considered
# valid; otherwise false.
def is_valid?
return false if @user.nil? || @project_id.nil?
return false if !@user.is_a?(User) || !@project_id.is_a?(Fixnum)
return false if !@user.is_valid?
true
end
end

我必须实现正确生成 JSON 输出的方法。当我在控制台中运行它时,会生成以下输出:

irb(main):004:0> r = Registration.new(:user => u, :project_id => 1)
=> new_login - nil - 1
irb(main):005:0> r.to_json
=> "{\"json_class\":\"Registration\",\"data\":[\"{\\\"json_class\\\":\\\"User\\\
",\\\"login\\\":\\\"new_login\\\"}\",1]}"

这对我来说看起来像是有效的 JSON。然而,当我将其发布到应用程序服务器并尝试对其进行解析时,JSON 提示至少需要 2 个八位字节并拒绝反序列化该对象。

最佳答案

如果您使用 Sequel 作为 ORM,请尝试以下操作:

在你的模型中:

class Registration < Sequel::Model
many_to_one :user
many_to_one :project
plugin :json_serializer
end

服务器:

before do
@data = JSON.parse(request.body.read) rescue {}
end

post '/users' do
@registration = Registration.new @data
if @registration.valid?
@registration.save
@registration.to_json #return a JSON representation of the resource
else
status 422 #proper status code for invalid input
@registration.errors.to_json
end
end

我认为您的注册过程可能过于复杂了。如果 HTTP 操作是 POST/users 那么为什么不创建一个用户呢?似乎创建一个 registration 过于复杂。除非您的用户已经存在,否则 POST/users 将是不正确的。如果您真正打算做的是将用户添加到项目中,那么您应该 PUT/projects/:project_id/users/:user_id 并且操作看起来像这样:

class User < Sequel::Model
many_to_many :projects
end
class Project < Sequel::Model
many_to_many :users
end
#make sure your db schema has a table called users_projects or projects_users

put '/projects/:project_id/users/:user_id' do
#find the project
@project = Project.find params[:project_id]
raise Sinatra::NotFound unless @project
#find the user
@user = Project.find params[:project_id]
raise Sinatra::NotFound unless @user
#add user to project's users collection
@project.add_user @user
#send a new representation of the parent resource back to the client
#i like to include the child resources as well
#json might look something like this
#{ 'name' : 'a project name', 'users' : ['/users/:user_id', '/users/:another_user_id'] }
@project.to_json
end

关于ruby - 为 Sinatra 生成 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9922336/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com