将阵列存储在导轨4中

时间:2015-10-27 13:35:49

标签: ruby-on-rails arrays

我正在寻找并遵循几个迹象,但我仍然坚持这一点。

我试图在interest_id列中存储一个数组。

这里的mi代码和追溯,似乎试图保存哈希而不是数组,问题是为什么?

迁移:

class CreateSearches < ActiveRecord::Migration
  def change
    create_table :searches do |t|
      t.integer :occasion_id
      t.integer :relationship_id
      t.integer :target_id
      t.integer :genre_id
      t.text :interest_id
      t.integer :user_id

      t.timestamps null: false
    end
  end
end

模型:

class Search < ActiveRecord::Base
  serialize :interest_id, Array
  def search_products
    products = Product.all
    products = Product.joins(:occasion_products).where(:occasion_products => {:occasion_id => occasion_id}) if occasion_id.present?
    products = Product.joins(:relationship_products).where(:relationship_products => {:relationship_id => relationship_id}) if relationship_id.present?
    products = Product.joins(:genre_products).where(:genre_products => {:genre_id => genre_id}) if genre_id.present?
    products = Product.joins(:target_products).where(:target_products => {:target_id => target_id}) if target_id.present?
    products = Product.joins(:interest_products).where(:interest_products => {:interest_id => interest_id}) if interest_id.present?
    return products
  end
end

控制器:

class SearchesController < ApplicationController
  def new
    @search = Search.new
  end
  def create
    @search = Search.create(search_params)
    redirect_to @search
  end
  def show
    @search = Search.find(params[:id])
  end

  private   
  def search_params
    params.require(:search).permit(:occasion_id, :relationship_id, :genre_id, :target_id, {:interest_id => []})
  end
end

回溯:

ActiveRecord::SerializationTypeMismatch in SearchesController#create
Attribute was supposed to be a Array, but was a Fixnum. -- 0
Extracted source (around line #6):

4
5
6
7
8
9




  end
  def create
    @search = Search.create(search_params)
    redirect_to @search
  end
  def show

Rails.root: /Users/emadobao/Sites/rails/personalgifter
Application Trace | Framework Trace | Full Trace

app/controllers/searches_controller.rb:6:in `create'

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"4mS9gQN8g/DWFab+Ecz77o2FTyGIY7/EezzCGXjkbIdmT4srMsixbFDEg25bgdVaOTuIUJRDedcKudYvPCDLgw==",
 "search"=>{"occasion_id"=>"1",
 "relationship_id"=>"1",
 "target_id"=>"1",
 "genre_id"=>"1",
 "interest_id"=>["",
 "2",
 "4"]},
 "commit"=>"Search"}

Toggle session dump
Toggle env dump
Response

Headers:

None

x
>> 

2 个答案:

答案 0 :(得分:0)

我认为你可能从一开始就接近这个问题。当然,技术上可以通过破解ActiveRecord将id列表推送到文本列中 - 但它不是Rails方式(甚至是非常好的方式)。

相反,您可以将关系定义为:

class Search
  has_and_belongs_to_many :products
end

class Product 
  has_and_belongs_to_many :searches
end

请注意,您无法在单个表上真正存储多对多关系 - 您无法将所有相关产品ID存储在searches表中,即使这似乎是一个很好的解决方案*。这不是关系数据库的工作方式。

为此,您需要创建一个连接表:

rails g migration CreateProductsSearchesJoinTable products searches  
rake db:migrate

创建一个这样的连接表:

create_table "products_searches", id: false, force: :cascade do |t|
  t.integer "product_id", null: false
  t.integer "search_id",  null: false
end

然后您可以通过以下方式分配产品:

@search.products << Product.where(foo: "bar")

答案 1 :(得分:0)

感谢Ogz的@max和@Wizard为您的approuchs。最后,我找到了一个深入了解我的代码的解决方案。

我只是创建一个新的模型InterestSearch,我修改了搜索和Intersest模型。这是最终的型号代码:

class InterestSearch < ActiveRecord::Base
  belongs_to :interest
  belongs_to :search
end

class Interest < ActiveRecord::Base
  has_many :interest_searches
  has_many :searches, :through => :interest_searches
end

class Search < ActiveRecord::Base
  has_many :interest_searches
  has_many :interests, :through => :interest_searches
  serialize :interest_id, Array
  def search_products
    products = Product.all
    products = products.joins(:occasion_products).where(:occasion_products => {:occasion_id => occasion_id}) if occasion_id.present?
    products = products.joins(:relationship_products).where(:relationship_products => {:relationship_id => relationship_id}) if relationship_id.present?
    products = products.joins(:genre_products).where(:genre_products => {:genre_id => genre_id}) if genre_id.present?
    products = products.joins(:target_products).where(:target_products => {:target_id => target_id}) if target_id.present?
    products = products.joins(:interest_products).where(:interest_products => {:interest_id => interest_ids}) if interest_ids.present?
    return products
  end
end