【问题标题】:Rails 4 has_many through - Message Sender & ReceiverRails 4 has_many through - 消息发送者和接收者
【发布时间】:2014-02-20 08:36:17
【问题描述】:

我正在尝试实现以下,关系和对象调用

一个用户可以发送许多消息(user.sent_messages) 一条消息可以有一个发件人(message.sender)

一个用户可以接收许多消息(user.received_messages) 一条消息可以有多个接收者(message.receivers)

我的架构如下所示:

create_table "activities", force: true do |t|
 t.integer  "sender_id"
 t.integer  "message_id"
 t.datetime "created_at"
 t.datetime "updated_at"
 t.integer  "receiver_id"
end

create_table "messages", force: true do |t|
 t.text     "body"
 t.datetime "created_at"
 t.datetime "updated_at"
 t.boolean  "read",       default: false
end

我的模型如下所示:

class User < ActiveRecord::Base
 has_many :activities, class_name: 'Activity', foreign_key: 'sender_id', dependent: :destroy
 has_many :sent_messages, through: :activities

 has_many :reverse_activities, class_name: 'Activity', foreign_key: 'receiver_id'
 has_many :received_messages, through: :reverse_activities
end

class Activity < ActiveRecord::Base
belongs_to :sent_messages, class_name: 'User'
belongs_to :received_messages, class_name: 'User'
belongs_to :message
end

class Message < ActiveRecord::Base
 has_many :activities, foreign_key: 'sender_id'
 has_one :sender, through: :activities, foreign_key: 'sender_id', class_name: 'User'

 has_many :reverse_activities, foreign_key: 'receiver_id', class_name: 'User'
 has_many :receivers, through: :reverse_activities, source: :receiver

end

sent_messages 和 received_messages 方法有效,但是它们直接指向 User 表并返回该用户的详细信息,而不是消息。

我还没有尝试让消息模型工作,因为用户模型不正确。

谢谢!


感谢这两个建议,我已经完成了以下工作

class User < ActiveRecord::Base

 has_many :activities, class_name: 'Activity', foreign_key: 'sender_id'
 has_many :sent_messages, through: :activities, foreign_key: 'message_id', class_name:     'Message', source: :sender

 has_many :reverse_activities, class_name: 'Activity', foreign_key: 'receiver_id'
 has_many :received_messages, through: :reverse_activities, foreign_key: 'message_id', class_name: 'Message', source: :receiver
end

class Message < ActiveRecord::Base
has_one :sent_activities, class_name: 'Activity', foreign_key: 'message_id'
has_one :sender, through: :sent_activities, foreign_key: 'sender_id', class_name: 'User'

has_many :receiver_activities, class_name: 'Activity', foreign_key: 'message_id'
has_many :receivers, through: :receiver_activities, foreign_key: 'receiver_id', class_name: 'User'

validates :body, presence: true
end

class Activity < ActiveRecord::Base
belongs_to :sender, class_name: 'User'
belongs_to :receiver, class_name: 'User'
belongs_to :receiver, class_name: 'Message'
belongs_to :sender, class_name: 'Message'
end

因此,我想要的方法有效。

现在只是为了让创建操作生效!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 rails-activerecord rails-models


    【解决方案1】:

    太复杂了

    你为什么不试试这个:

    #app/models/message.rb
    Class Message < ActiveRecord::Base
        belongs_to :sender, class_name: "User", primary_key: "sender_id"
        belongs_to :recipient, class_name: "User", primary_key: "recipient_id"
    end
    
    #app/models/user.rb
    Class User < ActiveRecord::Base
        has_many :sent_messages, class_name: "Message", foreign_key: "sender_id"
        has_many :received_messages, class_name: "Message", foreign_key: "recipient_id"
    end
    
    users
    id | name | email | created_at | updated_at
    
    messages
    id | sender_id | recipient_id | title | body | created_at | updated_at
    

    这将允许您像这样加载数据:

    @message.sender
    @message.recipient 
    
    @user.sent_messages
    @user.received_messages
    

    要保存数据,您可以使用:

    #app/controllers/messages_controller.rb
    def new
        @message = Message.new
    end
    
    def create
        @message = Message.new(message_params)
    end
    
    private
    
    def message_params
        params.require(:message).permit(:recipient_id, :title, :body).merge(sender_id: current_user.id)
    end
    
    #app/views/messages/new.html.erb (user has to be logged in)
    <%= form_for @message do |f| %>
        <%= f.collection_select(:recipient_id, User.all, :id, :name) %>
        <%= f.text_field :title %>
        <%= f.text_area :body %>
        <%= f.submit %>
    <% end %>
    

    【讨论】:

    • 嗨 Rich,谢谢,这一切看起来都很棒,除了这将限制我 a) 一条消息只能发送给一个人或 b) 必须复制整个消息内容以发送给多人。这是我试图用我的活动连接表抽象出来的。
    • 哦,我的印象是您只想要单个收件人/发件人?如果需要,我可以重构以包含连接表
    • 如果可能的话那就太好了!
    • 对于 rails 5 进度我得到错误我已经解决了它作为 belongs_to :sender, class_name: "User", foreign_key: "sender_id" belongs_to :recipient, class_name: "User", foreign_key: "recipient_id "
    【解决方案2】:

    Model Message中有一些错误:

    class Message < ActiveRecord::Base
    

    foreign_key 不应该是:“message_id”吗?

     has_many :activities, foreign_key: 'sender_id'
    

    foreign_key 中的同样问题:'sender_id',以及其他可能的问题

     has_one :sender, through: :activities, foreign_key: 'sender_id', class_name: 'User'
    
     has_many :reverse_activities, foreign_key: 'receiver_id', class_name: 'User'
     has_many :receivers, through: :reverse_activities, source: :receiver
    
    end
    

    您好像使用消息的 id 来加入其他表的发送者 ID 和接收 ID。

    class Activity < ActiveRecord::Base
    

    类名为'User',所以send_messages、received_messages返回用户信息

    belongs_to :sent_messages, class_name: 'User'
    belongs_to :received_messages, class_name: 'User'
    belongs_to :message
    end
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2017-09-26
      • 2014-10-12
      • 2013-08-13
      • 2013-08-25
      • 2019-10-01
      • 2021-06-30
      相关资源
      最近更新 更多