是否有一条 SQL 语句可以通过基于输入参数的 HABTM 关联返回适当数量的响应?

Posted

技术标签:

【中文标题】是否有一条 SQL 语句可以通过基于输入参数的 HABTM 关联返回适当数量的响应?【英文标题】:Is there a SQL statement that can return the appropriate number of responses through a HABTM association based on an input parameter? 【发布时间】:2021-11-22 07:15:06 【问题描述】:

我一直在尝试向我创建的 API 端点返回响应,并且响应运行良好,但我的问题是从名为 mobile 的对象返回适当数量的元素。

Request:

    "team_id": 4,
    "title": "Test message",
    "content": "This is a test message."


Response:

    "res": 
        "team_id": 4,
        "sms": 
            "id": "cd0a6e09-22de-46e2-a114-3a7cb2f29add",
            "mobile": [],
            "content": "This is a test message.",
            "sent_at": "2021-09-30T17:51:30.513+05:30"
        
    

我有三个模型:teammessagedeveloperteammessage 有一个 has many 并且属于(团队有很多消息并且消息属于团队)关联,而 teamdeveloper 有一个多对多关联。

Mobile 不应该为空,它应该是一个数组,其中包含根据一个团队下dev_ids 的数量在其中包含数字字符的字符串元素。 team_id 就其名称而言,仅存在于 message 中,但仍应充当它与 team 之间的外键。老实说,这里有点困惑我应该如何处理连接和东西。

团队举例:

team

        "id": 2,
        "name": "Pod-B",
        "dept_name": "Research",
        "created_at": "2021-09-20T16:48:49.306Z",
        "updated_at": "2021-09-23T06:01:00.722Z",
        "dev_ids": "[2, 4, 6]"
    

例如开发者:

developer 
   
        "id": 2,
        "full_name": "Aroosa Ahmed",
        "email": "arrosa@gmail.com",
        "mobile": "5593270301",
        "created_at": "2021-09-23T07:30:02.202Z",
        "updated_at": "2021-09-23T07:30:02.202Z"
    

我已经尝试了几种关于如何解决移动问题的变体,但正如您从我的控制器中看到的那样,它们都没有得到适当的响应。

trigger_controller

require 'securerandom'
class TriggerController < ApplicationController
    def notification
        @message = Message.new(message_params)
        @id = params[:team_id]
        @content = params[:content]
        @mob = Team.joins(:developers).where(id: @id).pluck(:mobile)
        #@mob = Team.joins(:developers).pluck(:mobile)
        #@mob = Team.includes(:developers).find(@id).pluck(:'developers.mobile')
        tim = Time.now

        if @message.save
          respond_to do |format|
            format.json  render json:  'res' => :team_id => @id, 'sms' =>  "id" => SecureRandom.uuid, :mobile => @mob, :content => @content, "sent_at" => tim    
          end
        else
            render json: @message.errors, status: :unprocessable_entity
        end

    end


    private
    # Use callbacks to share common setup or constraints between actions.
    def set_message
      @message = Message.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def message_params
      params.permit(:team_id, :title, :content)
    end
end

这里的架构可以更好地了解整个数据库:

schema.rb

ActiveRecord::Schema.define(version: 2021_09_30_043758) do

  create_table "developers", force: :cascade do |t|
    t.string "full_name"
    t.string "email"
    t.string "mobile"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "developers_teams", id: false, force: :cascade do |t|
    t.integer "team_id"
    t.integer "developer_id"
    t.index ["developer_id"], name: "index_developers_teams_on_developer_id"
    t.index ["team_id"], name: "index_developers_teams_on_team_id"
  end

  create_table "messages", force: :cascade do |t|
    t.integer "team_id", null: false
    t.string "title"
    t.text "content"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["team_id"], name: "index_messages_on_team_id"
  end

  create_table "teams", force: :cascade do |t|
    t.string "name"
    t.string "dept_name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "dev_ids", default: "--- []\n"
  end

  add_foreign_key "messages", "teams"
end

型号:

developer.rb

class Developer < ApplicationRecord
    validates :full_name, presence: true
    has_and_belongs_to_many :teams
end


team.rb

class Team < ApplicationRecord
    validates :name, presence: true
    has_many :messages
    serialize :dev_ids
    has_and_belongs_to_many :developers
end

【问题讨论】:

【参考方案1】:

认为我们都错过了 has_and_belongs_to_many 的乐趣,即拥有相关表作为方法。试试这个...

def notification
  @message = Message.new(message_params)
  @team_id = params[:team_id]
  @content = params[:content]
  @mob = Team.find(@team_id).developers.pluck(:mobile)
  tim = Time.now

  if @message.save
    respond_to do |format|
      format.json do
        render json:  'res' => :team_id => @team_id, 'sms' =>  "id" => SecureRandom.uuid, :mobile => @mob, :content => @content, "sent_at" => tim    
      end
    end
  else
    render json: @message.errors, status: :unprocessable_entity
  end

end

【讨论】:

遇到问题,它试图找到 developer.team_id 但实际上并不存在。 team_idmessage 上的外键,应该跟踪 team 上的默认 id。但在developers_teams 的连接表下还有team_id,所以我猜这就是你所引用的? 是的——我通常使用has_many,但改变了我的答案以利用HBTM。无法测试,所以 YMMV。

以上是关于是否有一条 SQL 语句可以通过基于输入参数的 HABTM 关联返回适当数量的响应?的主要内容,如果未能解决你的问题,请参考以下文章

一个list函数里面是否只能写一条sql语句

一条 SQL 语句是如何执行的

sql语句查询如何显示第一条数据

把俩条MySQL语句合并成一条

mybatis动态sql有这么一条语句:where a between #b and #c,a是数据的时间属性,b和c是要输入的时间点

基于星期几返回计数或空值的 Netezza SQL 语句