加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 为Sinatra生成JSON

发布时间:2020-12-17 02:31:28 所属栏目:百科 来源:网络整理
导读:我将生成的对象的 JSON表示法传递给我的Sinatra应用程序时出现问题.我遇到的问题有两个: 我有两个使用Sequel gem映射到数据库的类.当他们生成JSON时,它可以正常实现. 我有一个名为registration的自定义类,它使用一个附加字段映射其中一个类.目标是从中生成J
我将生成的对象的 JSON表示法传递给我的Sinatra应用程序时出现问题.我遇到的问题有两个:

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

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

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:我不能使用params哈希.它存在但只是一个空哈希.为什么?
>问题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.但是,当我将其POST到应用程序服务器并尝试解析时,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,那么为什么不创建用户呢?似乎创建注册过于复杂.除非您的用户已经存在,否则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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读