【问题标题】:Sinatra and Datamapper not able to save an array to the datatype ObjectSinatra 和 Datamapper 无法将数组保存到数据类型 Object
【发布时间】:2012-01-22 09:50:54
【问题描述】:

我有一个 HTML 表单,它使用以下 Sinatra 代码来处理 URL '/add-artist' 的 POST:

post '/add-artist' do
  if logged_in?
    a = Artist.new
    a.name = params[:name]
    a.website = params[:website]
    a.facebook = params[:facebook]
    a.created_by = session[:user_id]
    a.created_at = Time.now
    a.updated_by = session[:user_id]
    a_updated_at = Time.now
    a.views = 0
    a.save
    @user = User.get session[:user_id]
    @user.artists.push(a.id)
    @user.save
    redirect '/'
  end
end

正在保存对象“a”,但未保存“@user”。我想更具体地说,'@user.artists' 的值没有被更新。如果您需要更多信息,请询问,但我觉得你们 Ruby 专家会在我提供的代码中发现问题。

更新

这里有一些附加信息。我能够重现 irb 中的错误。首先这是我对“用户”的类定义。

# dm_models.rb
require 'data_mapper'

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/event_review.db") 

class User
  include DataMapper::Resource

  property :id, Serial
  property :email, String
  property :password, String
  property :user_name, String
  property :birthdate, Date
  property :city, String
  property :state, String
  property :zip, String
  property :geodata, Object
  property :bio, Text
  property :friends, Object
  property :events, Object
  property :event_reviews, Integer
  property :artists, Object
  property :artist_reviews, Integer
  property :venues, Object
  property :venue_reviews, Integer
  property :created_at, DateTime
  property :updated_at, DateTime
  property :views, Integer

  has n, :reviews

end

这是 irb

>> require 'sinatra'
=> true
>> require 'data_mapper'
=> true
>> require './models/dm_models.rb'
=> true
>> require 'geokit'
=> true
>> 
?> include Geokit::Geocoders
=> Object
>> u = User.get 8
=> #<User @id=8 @email="km@km.com" @password="km" @user_name="Katherine Miller" @birthdate=#<Date: 4895485/2,0,2299161> @city="Burbank" @state="CA" @zip="91501" @geodata=#<Geokit::GeoLoc:0x10150d4d8 @street_number=nil, @suggested_bounds=#<Geokit::Bounds:0x10150cf88 @sw=#<Geokit::LatLng:0x10150cd80 @lng=-118.315043, @lat=34.1766949>, @ne=#<Geokit::LatLng:0x10150cee8 @lng=-118.27996, @lat=34.221666>>, @lng=-118.2935891, @zip="91501", @state="CA", @precision="zip", @province=nil, @all=[#<Geokit::GeoLoc:0x10150d4d8 ...>], @street_address=nil, @provider="google", @city="Burbank", @lat=34.2039087, @country_code="US", @full_address="Burbank, CA 91501, USA", @street_name=nil, @accuracy=5, @country="USA", @success=true> @bio=<not loaded> @friends=[] @events=["13", "14", "15", "16", "28", "29"] @event_reviews=7 @artists=[] @artist_reviews=1 @venues=[] @venue_reviews=0 @created_at=#<DateTime: 70729968253/28800,-5/24,2299161> @updated_at=#<DateTime: 1178838019/480,-5/24,2299161> @views=56>
>> 
?> u.artists
=> []
>> u.artists.push "5"
=> ["5"]
>> u.save
=> true
>> u = User.get 8
=> #<User @id=8 @email="km@km.com" @password="km" @user_name="Katherine Miller" @birthdate=#<Date: 4895485/2,0,2299161> @city="Burbank" @state="CA" @zip="91501" @geodata=#<Geokit::GeoLoc:0x1014e8638 @street_number=nil, @suggested_bounds=#<Geokit::Bounds:0x1014e80e8 @sw=#<Geokit::LatLng:0x1014e7eb8 @lng=-118.315043, @lat=34.1766949>, @ne=#<Geokit::LatLng:0x1014e8048 @lng=-118.27996, @lat=34.221666>>, @lng=-118.2935891, @zip="91501", @state="CA", @precision="zip", @province=nil, @all=[#<Geokit::GeoLoc:0x1014e8638 ...>], @street_address=nil, @provider="google", @city="Burbank", @lat=34.2039087, @country_code="US", @full_address="Burbank, CA 91501, USA", @street_name=nil, @accuracy=5, @country="USA", @success=true> @bio=<not loaded> @friends=[] @events=["13", "14", "15", "16", "28", "29"] @event_reviews=7 @artists=[] @artist_reviews=1 @venues=[] @venue_reviews=0 @created_at=#<DateTime: 70729968253/28800,-5/24,2299161> @updated_at=#<DateTime: 1178838019/480,-5/24,2299161> @views=56>
>> u.artists
=> []
>> u.artists.class
=> Array

上面代码的描述:我用 id==8 检索用户,将值“5”压入其中。这似乎是成功的。我保存用户#8。然后我重新检索 user#8 并查看艺术家的值,它是一个空数组。

最后,我可以更新“artist_reviews”等其他字段。这是因为我将艺术家、活动和场所的数据类型定义为“对象”吗?所有这些字段都存在这个问题。

感谢您的帮助。

【问题讨论】:

    标签: ruby arrays object sinatra datamapper


    【解决方案1】:

    日志是怎么说的?你能推到@user.artists 吗?它是一个数组吗?它可能无法通过验证,您无法完成保存。

    【讨论】:

    • 我能够在 irb 中重现该错误,因此应该更容易弄清楚。我将使用该信息编辑我的问题。
    • 为什么艺术家需要对象?似乎您想要一个数组,但不能将“5”推入对象。我假设如果您选择 Object ,您将不得不使用 Artist= 然后将对象编组到该属性中。
    • 完全披露,我只使用 Ruby 大约一个月,所以我没有充分的理由使用数据类型“对象”。我在 datamapper 文档中没有看到任何关于使用 Array 数据类型的内容,所以我猜想在 Ruby 中 Array 是一个 Object,所以它可能会起作用。奇怪的是,到目前为止,它实际上已经完成了。我想我只是要改变我试图解决的问题的方法,而不是继续为此而努力。我认为使用“has_n”和“belongs_to”关联我将能够完成我需要完成的事情。
    【解决方案2】:

    我前段时间问过这个问题,但我很确定解决方案是序列化对象。在这种情况下,它是一个整数数组。我不确定我是否有时间用详细的解决方案来更新它,但数组不能直接存储在关系数据库中。数组对象必须“序列化”,本质上转换为字符串。在此示例中,artist 属性的数据类型将是 text.

    您可以手动将艺术家列转换为数组(从字符串)将新整数推送到数组中,然后转换回字符串并保存。我假设有一种自动化的方法可以做到这一点,但这就是想法。

    此外,整个示例是处理关联的糟糕方法。更好的方法是建立一个一对多的关联,其中有一个ArtistUser 表,它有两列artist_iduser_id。每个新关联都表示为ArtistUser 表中的一个新行。

    【讨论】:

      猜你喜欢
      • 2016-01-06
      • 2016-07-28
      • 2011-01-19
      • 1970-01-01
      • 2014-06-30
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多