Синатра и Datamapper не могут сохранить массив в объект типа данных - PullRequest
3 голосов
/ 17 декабря 2011

У меня есть HTML-форма, которая использует следующий код Sinatra для обработки POST для URL '/ add-artist':

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.Затем я повторно извлекаю пользователя # 8 и смотрю на значение Artist, и это пустой массив.

И, наконец, я могу обновить другие поля, такие как "artist_reviews".Это потому, что я определяю тип данных как «Объект» для художников, событий и мест проведения?Эта проблема существует для всех этих полей.

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2013

Я спрашивал об этом некоторое время назад, но я почти уверен, что решение состоит в том, чтобы сериализовать объект. В данном случае это был массив целых чисел. Я не уверен, что у меня будет время обновить это подробным решением, но массив не может быть сохранен непосредственно в реляционной базе данных. Объект массива должен быть «сериализован», по существу преобразован в строку. В этом примере тип данных для атрибута artist будет тогда text.

Вы можете вручную преобразовать столбец Artist в массив (из строки), вставить новое целое число в массив, а затем преобразовать обратно в строку и сохранить. Я предполагаю, что есть автоматизированный способ сделать это, но это идея.

Кроме того, весь этот пример - плохой способ обработки ассоциаций. Лучший способ сделать это - создать связь «один ко многим», в которой есть таблица ArtistUser с двумя столбцами artist_id и user_id. Каждая новая ассоциация представляется в виде новой строки в таблице ArtistUser.

0 голосов
/ 17 декабря 2011

Что говорят логи? Можете ли вы нажать на @ user.artists? Это массив? Это может не пройти проверку, и вы не можете завершить сохранение.

...