ruby-on-rails - 将对象转换为散列然后将其保存到用户的列

标签 ruby-on-rails ruby ruby-on-rails-4

找不到与我正在尝试做的事情相近的东西。我想将一个对象存储到用户的列中。该列为数组形式:

#postgres
def change
  add_column :users, :interest, :string, array: true, default: '{}'
end

我有另一个名为 FooBar setup 的模型用于其他用途。由于我添加了一个 user_id 键,因此每个用户内部都有唯一的信息。

我试图使更有意义:

def interest
 @user = User.find(current_user.id ) # I need the logged in user's id
 @support = Support.find(params[:id]) # I need the post's id they are on
 u = FooBar.new
 u.user_id = @user
 u.support_id = @support
 u.save # This saves a new Foo object..this is what I want

 @user.interest.push(FooBar.find(@user)) # This just stores the object name itself ;)
end

因此,当我调用 u1 = FooBar.find(1) 时,我得到了散列中的返回值。我希望当我说 u1.interest 时,我得到了同样的结果。原因是,我需要针对用户即这些键:u1.interest[0].support_id

这可能吗?我查看了我的基本 ruby​​ 文档,但没有任何效果。哦..如果我通过了 FooBar.find(@user).inspect 我得到了哈希值但不是我想要的方式。

我正在尝试做类似于 stripe 的事情.查看他们的 data 键。那是一个哈希。

为 Rich 编辑的答案:

从字面上看,我有一个名为 UserInterestSent 的模型和表:

class UserInterestSent < ActiveRecord::Base
  belongs_to :user
  belongs_to :support # you can call this post
end

class CreateUserInterestSents < ActiveRecord::Migration
  def change
    create_table :user_interest_sents do |t|
      t.integer :user_id # user's unique id to associate with post (support)
      t.integer :interest_sent, :default => 0 # this will manually set to 1
      t.integer :support_id, :default => 0 # id of the post they're on

      t.timestamps # I need the time it was sent/requested for each user
    end
  end
end 

我调用 interest interest_already_sent:

supports_controller.rb:

  def interest_already_sent
    support = Support.find(params[:id])
    u = UserInterestSent.new(
      {
        'interest_sent' => 1, # they can only send one per support (post)
        'user_id' => current_user.id, # here I add the current user
        'support_id' => support.id, # and the post id they're on
      }) 
        current_user.interest << u # somewhere this inserts twice with different timestamps
  end 

而且兴趣不是兴趣,专栏:

class AddInterestToUsers < ActiveRecord::Migration
  def change
    add_column :users, :interest, :text
  end
end

最佳答案

H商店

我记得有一个 PGSQL 数据类型叫做 hStore :

This module implements the hstore data type for storing sets of key/value pairs within a single PostgreSQL value. This can be useful in various scenarios, such as rows with many attributes that are rarely examined, or semi-structured data. Keys and values are simply text strings.

Heroku supports it我已经看到它用于我正在观察的另一个实时应用程序。

它不会以与 Stripe 相同的方式存储您的对象的 data属性(为此,您只需要使用 text 并保存对象本身),但您可以存储一系列 key:value对(JSON)。

我以前从未使用过它,但我想您可以将一个 JSON 对象发送到该列,这样您就可以使用您需要的属性。有一个 good tutorial here , 和 Rails documentation here :

# app/models/profile.rb
class Profile < ActiveRecord::Base
end

Profile.create(settings: { "color" => "blue", "resolution" => "800x600" })

profile = Profile.first
profile.settings # => {"color"=>"blue", "resolution"=>"800x600"}

profile.settings = {"color" => "yellow", "resolution" => "1280x1024"}
profile.save!

--

这意味着您应该能够将 JSON 对象传递给您的 hstore专栏:

#app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
   def update 
      @profile = current_user.profile
      @profile.update profile_params
   end

   private

   def profile_params
      params.require(:profile).permit(:x, :y, :z) #-> z = {"color": "blue", "weight": "heavy"}
   end
end

根据您的评论,在我看来,您正试图将“兴趣”存储在 User 中。来自另一个模型。

我的第一个解释是您想在 @user.interests 中存储信息的散列柱子。也许你会有 {name: "interest", type: "sport"}什么的。

从您的评论来看,您似乎想要在此列中存储关联的对象/数据。如果是这种情况,您的做法应该是使用 ActiveRecord association .

如果您不知道这是什么,它本质上是一种通过数据库中的外键将两个或多个模型连接在一起的方法。您设置它的方式将决定您可以存储什么以及如何...

#app/models/user.rb
class User < ActiveRecord::Base
   has_and_belongs_to_many :interests,
      class_name: "Support",
      join_table: :users_supports,
      foreign_key: :user_id,
      association_foreign_key: :support_id
end

#app/models/support.rb
class Support < ActiveRecord::Base
  has_and_belongs_to_many :users,
      class_name: "Support",
      join_table: :users_supports,
      foreign_key: :support_id,
      association_foreign_key: :user_id
end

#join table = users_supports (user_id, support_id)

通过使用它,您可以填充 .interests.users方法分别为:

#config/routes.rb
resources :supports do
   post :interest #-> url.com/supports/:support_id/interest
end

#app/controllers/supports_controller.rb
class SupportsController < ApplicationController
   def interest
       @support = Support.find params[:support_id] # I need the post's id they are on
       current_user.interests << @support
   end
end

这样您就可以调用 @user.interests并带回一组 Support对象。


好的,看。

我建议的是使用 interest替代方法专栏。

您似乎想为关联模型存储一系列哈希值。这正是many-to-many关系是为了。

您的数据被填充两次的原因是因为您调用它两次( u= 直接在连接模型上创建记录,然后您使用 << 插入更多数据)。

我必须补充一点,在两个 实例中,正确的 行为都在发生;正在填充连接模型,允许您调用关联的对象。

你想要的是这样的:

enter image description here

def interest_already_sent
    support = Support.find params[:id]
    current_user.interests << support
end 

使用我推荐的方法时,去掉 interest专栏

您可以调用.interests 通过您的连接表

当使用上面的代码时,它告诉 Rails 插入 support对象(IE support_idcurrent_user (IE user_id ) interests 关联(用 UserInterestSelf 表填充)。

这基本上会在这个表中添加一个新记录 user_idcurrent_usersupport_idsupport .

关于ruby-on-rails - 将对象转换为散列然后将其保存到用户的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33097689/

相关文章:

ruby-on-rails - 依赖销毁不起作用,has_many :model, :dependent => :destroy

php - 如果内存过度使用,哪个进程会被内核杀死? child 还是 parent ?

ruby-on-rails - Heroku Redis 无法打开连接

css - 安装 Bootstrap gem 后如何覆盖/更改 Ruby on Rails spree 应用程序的布局?

ruby - 更新 Rubygems?

ruby-on-rails - Heroku:为什么有这么多数据库连接?

python - 您如何读取单个 cUrl block ?

ruby-on-rails - 错误 R14(超出内存配额)+ Heroku + Passenger

php - 在 ROR 中使用什么 : Class or Module,

ruby-on-rails - Rails 模块作为严格的命名空间