【问题标题】:What does the `<>` in Rails query mean?Rails 查询中的 `<>` 是什么意思?
【发布时间】:2016-03-12 09:18:33
【问题描述】:

我很难搜索符号的含义,例如 &lt;&gt; 在 rails 查询中的含义。那么&lt;&gt; 是什么意思呢? (或者一般来说,您如何在 Google 上搜索 &lt;&gt; 之类的内容?)

简而言之

用简单的英语,以下查询是什么意思?

查询 1:

@profile.socials.all.where.not(kind: [2, 3])

查询 2:

@profile.socials.where("kind <> ?", "[:facebook, :linked_in]")

注意 1:kind 的数据类型为 enum,如下所示:

enum kind: [ :twitter, :google_plus, :facebook, :linked_in, :skype, :yahoo ]

注意 2:两个查询在控制台窗口中产生相同的结果。我相信这两个查询都旨在对子集数据进行where 查询(使用不等于运算符)。我只是不知道如何解释&lt;&gt;

详细 Rails 应用程序

这些是我的模型:

型号Profile

class Profile < ActiveRecord::Base
  has_many :socials, as: :sociable, dependent: :destroy
  accepts_nested_attributes_for :socials, allow_destroy: true
end

型号Social

class Social < ActiveRecord::Base
  enum kind: [ :twitter, :google_plus, :facebook, :linked_in, :skype, :yahoo ]
  belongs_to :sociable, polymorphic: true
  validates_presence_of :kind
  validates_presence_of :username
end

迁移文件:

class CreateProfiles < ActiveRecord::Migration
  def change
    create_table :profiles do |t|
      t.string :first_name
      t.string :last_name
      t.timestamps null: false
    end
  end
end


class CreateSocials < ActiveRecord::Migration
  def change
    create_table :socials do |t|
      t.integer :kind, null: false
      t.string :username
      t.references :sociable, polymorphic: true, index: true

      t.timestamps null: false
    end
    add_index :socials, :kind
    add_index :socials, :username
  end
end

这是我的架构的样子:

ActiveRecord::Schema.define(version: 20160311132502) do

  create_table "profiles", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "socials", force: :cascade do |t|
    t.integer  "kind",          null: false
    t.string   "username"
    t.integer  "sociable_id"
    t.string   "sociable_type"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
  end

  add_index "socials", ["kind"], name: "index_socials_on_kind"
  add_index "socials", ["sociable_type", "sociable_id"], name: "index_socials_on_sociable_type_and_sociable_id"
  add_index "socials", ["username"], name: "index_socials_on_username"

end

 控制台输入

@profile = Profile.new
@profile.first_name = parameter[:profile][:first_name]
@profile.last_name = parameter[:profile][:last_name]
@profile.socials_attributes = parameter[:profile][:socials_attributes]
@profile.save
@profile = Profile.last
@profile.socials.kinds
@profile.socials.all.where(kind: 2) # => gives you the user facebook account
@profile.socials.all.where(kind: :facebook) # => Apparently only works in Rails 5 or above.

@profile.socials.all.where(kind: [2, 3]) # => gives you the user facebook and linked_in account
@profile.socials.all.where(kind: [:facebook, :linked_in]) # => Apparently only works in Rails 5 or above.

控制台提示 - Rails 4 解决方法(Rails 5 中不需要)

这两个查询是等价的(只选择用户的 facebook 帐户):

@profile.socials.all.where(kind: 2)

@profile.socials.all.where(kind: @profile.socials.kinds.keys.find_index("facebook"))

这两个查询是等价的(只选择用户的facebook和linked_in账号):

@profile.socials.all.where(kind: [2, 3])

@profile.socials.all.where(kind: [@profile.socials.kinds.keys.find_index("facebook"), @profile.socials.kinds.keys.find_index("linked_in")])

【问题讨论】:

    标签: sql ruby-on-rails


    【解决方案1】:

    &lt;&gt; 是 SQL 语法,而不是 Ruby 或 Rails。这意味着not equal to。与Ruby中的!=基本相同。

    SQL 中&lt;&gt; 的一个微妙之处在于它与NULLs 的行为。在 SQL 中,将任何内容与NULL 进行比较得到NULL。例如在 Postgres 中:

    => select 1<>1, 1<>2, 1<>null, null<>1, null<>null;
     ?column? | ?column? | ?column? | ?column? | ?column? 
    ----------+----------+----------+----------+----------
     f        | t        | NULL     | NULL     | NULL
    

    注意最后一个表达式是NULL!通常这不是您想要的,您可以改用IS DISTINCT FROM

    => select null is distinct from 1, null is distinct from null;
     ?column? | ?column? 
    ----------+----------
     t        | f
    

    编辑:解决您的后续问题:在您的数据库中kind 是一个整数。所以你想将它与整数进行比较:

    @profile.socials.where.not(kind: [2, 3])
    

    或者如果您使用的是Rails 5

    @profile.socials.where.not(kind: [:facebook :linked_in])
    

    因为 Rails 5 会自动使用您的 enum 声明将这些符号转换为适当的整数,所以上述方法有效。

    【讨论】:

    • 哦,是的 &lt;&gt; 在 SQLIte 中确实意味着 not equal to(此 Rails 应用程序的构建所在)。然而,根据查询,它似乎暗示相反的意思?例如@profile.socials.where("kind &lt;&gt; ?", "[:facebook, :linked_in]")@profile.socials.all.where(kind: [2, 3]) 都返回观察社交媒体类型的位置 kind: 2 (:facebook) 或 kind: 3 (:linked_in)。还是我错过了什么? (ps 我只使用 Ruby/Rails 2 个月,还是个新手 :)
    • 实际上,我不太确定@profile.socials.where("kind &lt;&gt; ?", "[:facebook, :linked_in]") 是否真的正确/不正确...让我检查一下...
    • 感谢您的帮助!这部分正在工作:@profile.socials.all.where(kind: [2, 3])(给我:facebook:linked_in 帐户),同样@profile.socials.all.where(kind: [2]) 只给我:facebook 帐户。我想我想要做的是(为了我自己的好奇心 :) 构建一个等效查询(利用枚举),在其中我可以做类似@profile.socials.all.where(kind: [:facebook, :linked_in])@profile.socials.all.where(kind: [:facebook]) 的事情 - 即代替@987654353 @,我说where kind is one of these english symbols
    • 刚刚发现了一个(可能不是那么优雅的解决方案)。即 @profile.socials.where(kind: 2) 的等价物是 Rails 4 中的 @profile.socials.all.where(kind: @profile.socials.kinds.keys.find_index("facebook"))
    • 这很冗长,但比仅仅要求2更清楚。
    猜你喜欢
    • 2014-09-14
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2011-05-26
    • 2021-07-16
    • 2014-10-16
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多