【问题标题】:Delete value from serialized Array in ActiveRecord model从 ActiveRecord 模型中的序列化数组中删除值
【发布时间】:2017-10-16 06:09:56
【问题描述】:

我有一个 Rails 模型设置为:

class Master < ActiveRecord::Base
  belongs_to :user
  has_many :submasters
  serialize :subdocs, Array
end

它有一个序列化的arraysubmaster_docs 存储连接的subdocsid 和我的Subdocs 的模型是:

class Subdocs < ActiveRecord::Base
  belongs_to :user
end

现在我有一个 rails 方法,当用户单击删除按钮时,它会删除 subdoc

在删除 Subdocs 条目时,我想从 Master 中删除 Subdocs 的 id,这样即使在删除 Subdocs 后它也不会尝试在它们之间创建关联

我的Master 数据库条目如下所示:

<ActiveRecord::Relation [#<Master id: 3, user_id: 1, name: "Being Batman", description: "Every man who has lotted here over the centuries, ...", subdocs: ["5"]>]> 

subdoc的数据库入口:

<ActiveRecord::Relation [#<Subdoc id: 5, user_id: 1, name: "subdoc1.pdf">]> 

例如,如果用户删除了 subdoc 5,那么我想从所有 Mastersubdocs 数组中删除该值

我删除子文档的方法如下:

def destroy
  @masters = {}
  @subdoc = Subdoc.find(params[:id])
  @masters = current_user.user.masters

  # Tried these methods to delete the value.
  # @subdocs = @masters.select { |t| t.subdocs.to_a - [params[:id]] }
  # @subdocs = @masters.each { |t| t[:subdocs] - params[:id] }   

  @subdoc.destroy
  return render :status => 200, :json => { :success => true }    
end

但这给我带来了错误:No Implicit conversion of String into Array

我该如何纠正这个问题?谢谢!

【问题讨论】:

    标签: ruby-on-rails arrays ruby activerecord


    【解决方案1】:

    您不想在这里使用数组。尤其不是序列化数组:

    • 您必须扫描字符串才能在查询中使用该列。
    • ActiveRecord 关联用于处理实际的外键列。关系数据库也是如此。
    • 您没有参照完整性。

    所以首先创建一个迁移rails g migration add_master_to_subdocs

    class AddMasterToSubdocs < ActiveRecord::Migration[5.0]
      def change
        add_reference :subdocs, :master, foreign_key: true
        remove_column :subdocs, :user_id
      end
    end
    

    我们还将删除 user_id 列,因为它不再需要:

    class Master < ActiveRecord::Base
      belongs_to :user
      has_many :submasters
      has_many :subdocs
    end
    
    class Subdocs < ActiveRecord::Base
      belongs_to :master
      has_one :user, through: :master
    end
    

    【讨论】:

    • 如果您希望 Subdoc 属于多个 Master,则使用连接表并将关联声明为 has_many :through
    • 虽然你说的在逻辑上是有道理的,但我正在处理一个遗留应用程序,我不允许对数据库进行更改。我需要使用现有的表和模型来做到这一点:/
    • 我想我唯一的建议就是尽快逃离这个项目。
    【解决方案2】:

    虽然我同意 max 并且您不应该使用此架构,但假设您保持原样,您将需要从 master 中的数组中删除该项目并保存 master。

    def destroy
      @masters = {}
      @subdoc = Subdoc.find(params[:id])
      @masters = current_user.user.masters
      @masters.each do |master| 
        if master.subdocs.index(params[:id])
          master.subdocs.delete(params[:id])
          master.save!
        end
      end  
    
      @subdoc.destroy
      return render :status => 200, :json => { :success => true }    
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-26
      • 2016-11-26
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      相关资源
      最近更新 更多