将对象转换为哈希,然后将其保存到用户的列 [英] Convert an Object to hash then save it to user's column

查看:41
本文介绍了将对象转换为哈希,然后将其保存到用户的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

#postgres定义改变add_column :users, :interest, :string, array: true, default: '{}'结尾

我有另一个名为 FooBar setup 的模型供其他用途.因为我添加了一个 user_id 键,所以每个用户都有独特的信息.

我想说得更有意义:

def 兴趣@user = User.find(current_user.id) # 我需要登录用户的 id@support = Support.find(params[:id]) # 我需要他们所在的帖子的 idu = FooBar.newu.user_id = @useru.support_id = @supportu.save # 这会保存一个新的 Foo 对象..这就是我想要的@user.interest.push(FooBar.find(@user)) # 这只是存储对象名称本身;)结尾

因此,当我调用 u1 = FooBar.find(1) 时,我以哈希形式返回值.我希望当我说 u1.interest 时我得到相同的结果.原因是,我需要将这些键定位在用户身上,即:u1.interest[0].support_id

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

我正在尝试做一些类似于

def interest_already_sentsupport = Support.find params[:id]current_user.interests <<支持结尾

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

您可以通过加入表调用.interests.

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

这基本上会向这个表添加一个新记录,其中 current_useruser_idsupportsupport_id代码>.

Could not find nothing close to what I'm trying to do. I want to store an object into a user's column. That column is in the form of an array:

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

I have another model called FooBar setup for other use. Each user has unique information inside as I've added a user_id key.

Im trying to make more sense:

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

So when I call u1 = FooBar.find(1) I get value return in hash. I want when I say u1.interest I get the same. The reason is, I need to target those keys on the user ie: u1.interest[0].support_id

Is this possible? I've looked over my basic ruby docs and nothing works. Oh..if I passed FooBar.find(@user).inspect I get the hash but not the way I want it.

Im trying to do something similar to stripe. Look at their data key. That's a hash.

Edit for Rich' answer:

I have, literally, a model called UserInterestSent model and table:

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 

I call 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 

And the interest not interests, column:

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

解决方案

HStore

I remembered there's a PGSQL datatype called 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 and I've seen it used on another live application I was observing.

It won't store your object in the same way as Stripe's data attribute (for that, you'll just need to use text and save the object itself), but you can store a series of key:value pairs (JSON).

I've never used it before, but I'd imagine you can send a JSON object to the column, and it will allow you to to use the attributes you need. There's a good tutorial here, and 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!

--

This means you should be able to just pass JSON objects to your hstore column:

#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


As per your comments, it seems to me that you're trying to store "interest" in a User from another model.

My first interpretation was that you wanted to store a hash of information in your @user.interests column. Maybe you'd have {name: "interest", type: "sport"} or something.

From your comments, it seems like you're wanting to store associated objects/data in this column. If this is the case, the way you're doing it should be to use an ActiveRecord association.

If you don't know what this is, it's essentially a way to connect two or more models together through foreign keys in your DB. The way you set it up will determine what you can store & how...

#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)

by using this, you can populate the .interests or .users methods respectively:

#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

This will allow you to call @user.interests and bring back a collection of Support objects.


Okay, look.

What I suggested was an alternative to using interest column.

You seem to want to store a series of hashes for an associated model. This is exactly what many-to-many relationships are for.

The reason your data is being populated twice is because you're invoking it twice (u= is creating a record directly on the join model, and then you're inserting more data with <<).

I must add that in both instances, the correct behaviour is occurring; the join model is being populated, allowing you to call the associated objects.

What you're going for is something like this:

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

When using the method I recommended, get rid of the interest column.

You can call .interests through your join table.

When using the code above, it's telling Rails to insert the support object (IE support_id into the current_user (IE user_id) interests association (populated with the UserInterestSelf table).

This will basically then add a new record to this table with the user_id of current_user and the support_id of support.

这篇关于将对象转换为哈希,然后将其保存到用户的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆