gpt4 book ai didi

ruby-on-rails - Rails 用户到用户消息

转载 作者:行者123 更新时间:2023-12-04 05:46:42 25 4
gpt4 key购买 nike

我对 Rails 很陌生,所以请在您的回复中详细说明。我正在构建一个使用设计进行身份验证的网络应用程序。我现在坚持的部分是用户到用户的消息传递系统。这个想法是用户 A 登录应用程序并可以访问用户 B 的个人资料,并且在用户 B 的个人资料上可以单击允许用户 A 向用户 B 撰写消息的链接。然后用户 B 可以登录应用程序并访问将在其中找到用户 A 的消息的收件箱。

我相信我在这里定义发件人和收件人角色时遇到了麻烦,现在我正在尝试显示用户将在其中撰写邮件的表单。谁能看到我在这里做错了什么?我收到以下错误。我已经读到要做的事情是将 User_id 字段添加到表中,但我希望使用 sender_id 和 recipient_id 将这些消息链接起来,它们都等于 user_id(例如,用户 1[sender] 向用户 2 发送消息[接受者]):

未知属性:user_id

定义新
@message = current_user.messages.new 收件人 ID:参数 [:发件人 ID]
结尾

此外,对于您的铁路专家或做过类似事情的任何人,您能否建议我是否朝着正确的方向前进,或提供任何指导?我在这里有点编码盲,只是想在我前进的过程中弥补它。任何指导将不胜感激,并为我节省大量时间,我敢肯定。下面的代码:

用户迁移

class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
t.string :first_name
t.string :last_name
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""

t.string :reset_password_token
t.datetime :reset_password_sent_at

t.datetime :remember_created_at

t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip

t.timestamps
end

add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true

end
end

消息迁移
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.string :content
t.integer :sender_id
t.integer :recipient_id
t.timestamps
end
end
end

架构.rb
ActiveRecord::Schema.define(version: 20140909174718) do

create_table "messages", force: true do |t|
t.string "content"
t.integer "sender_id"
t.integer "recipient_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "users", force: true do |t|
t.string "first_name"
t.string "last_name"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "current_industry"
t.integer "years_in_current_industry"
t.string "hobbies"
end

add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

路线.rb
Catalyst::Application.routes.draw do

devise_for :users, :controllers => { :registrations => "registrations" }

devise_scope :user do
get 'register', to: 'devise/registrations#new'
get 'login', to: 'devise/sessions#new', as: :login
get 'logout', to: 'devise/sessions#destroy', as: :logout
end

resources :users do
member do
get 'edit_profile'
end
resources :messages, only: [:new, :create]
end

resources :messages, only: [:index, :show, :destroy]

root to: "home#index"
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/legal', to: 'static_pages#legal', via: 'get'

end

users_controller
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
@users = User.all
end

def show
@user = User.find(params[:id])
end

def new
end

def create
end

def edit
end

def update
@user = User.find(params[:id])
@user.update!(user_params)
redirect_to @user
end

def destroy
end

def edit_profile
@user = User.find(params[:id])
end

def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_industry, :years_in_current_industry, :hobbies)
end

def sender
@user = User.find(params[:id])
end

def recipient
@user = User.find(params[:id])
end

end

消息 Controller
class MessagesController < ApplicationController
before_action :set_recipient

def new
@message = Message.new
@recipient = User.find(params[:user_id])
end

def create
@message = Message.new message_params
if @message.save
flash[:success] = "Your message has been sent!"
redirect_to user_messages_path
else
flash[:failure] = "Please try again."
redirect_to users_path
end
end

private

def message_params
params.require(:message).permit(:content, :sender_id, :recipient_id)
end
end

用户.rb
class User < ActiveRecord::Base
has_many :from_messages, class_name: 'Message', :foreign_key => "sender_id"
has_many :to_messages, class_name: 'Message', :foreign_key => "recipient_id"

devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable

attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :remember_me, :current_industry, :years_in_current_industry, :hobbies

end

消息.rb
class Message < ActiveRecord::Base
belongs_to :sender, class_name: "User"
belongs_to :recipient, class_name: "User"

validates :content, presence: true, length: { maximum: 500 }
validates :sender_id, presence: true
validates :recipient_id, presence: true
end

消息/index.html.erb
<h2>Inbox</h2>

消息/new.html.erb
<h1>Create Message</h1>

<%= form_for [@recipient, @message] do |f| %>

<%= f.hidden_field :recipient_id, value: @recipient.id %>

<%= f.label "Enter your message below" %><br />
<%= f.text_area :content %>

<%= f.submit "Send" %>
<% end %>

rake 路线
user_messages POST   /users/:user_id/messages(.:format)     messages#create
new_user_message GET /users/:user_id/messages/new(.:format) messages#new
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
messages GET /messages(.:format) messages#index
message GET /messages/:id(.:format) messages#show
DELETE /messages/:id(.:format) messages#destroy

最佳答案

型号

#app/models/user.rb
class User < ActiveRecord::Base
has_many :messages, class_name: "Message", foreign_key: "recipient_id"
has_many :sent_messages, class_name: "Message", foreign_key: "sender_id"
end

#app/models/message.rb
class Message < ActiveRecord::Base
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
scope :unread, -> { where read: false }
end

这应该使您能够创建“属于”用户(即收件人)的消息,然后您可以将“发件人”配置文件与这些消息相关联。

--

Controller

这将使您能够调用以下内容:
#app/controllers/messages_controller.rb
class MessagesController < ApplicationController
before_action :set_recipient, only: [:new, :create]

def new
@message = current_user.sent_messages.new
end

def create
@message = current_user.sent_messages.new message_params
@message.recipient_id = @recipient.id
@message.save
end

def index
@messages = current_user.messages
end

def destroy
@message = current_user.messages.destroy params[:id]
end

def show
@message = current_user.messages.find params[:id]
end

private

def message_params
params.require(:message).permit(:content, :recipient_id, :sender_id)
end

def set_recipient
@recipient = User.find params[:user_id]
end
end

--

路线
#config/routes.rb
devise_for :users, path: "", controllers: { :registrations => "registrations" }, path_names: {sign_up: "register", sign_in: "login", sign_out: "logout"}

resources :users do
get :profile
resources :messages, only: [:new, :create] #-> domain.com/users/:user_id/messages/new
end
resources :messages, only: [:index, :show, :destroy] #-> domain.com/messages/:id

--

浏览量

这将使您能够使用以下链接:
#app/views/users/show.html.erb (user to send message to)
<%= link_to "Send Message", user_messages_path(@user.id) %>

#app/views/messages/new.html.erb
<%= form_for [@recipient, @user] do |f| %>
<%= f.text_field :content %>
<%= f.submit %>
<% end %>

#app/views/messages/index.html.erb
<h2>Inbox</h2>
<% @messages.each do |message| %>
<%= message.content %>
<% end %>

--

修复

I've read that the thing to do is add the User_id field to the table, but I'm hoping to link this messages up using sender_id and recipient_id, which both equal user_id (e.g. User 1[sender] sends a message to User 2 [recipient])



不要需要添加 user_id到你的 table 。 user_id只是一个 foreign_key ,您已在 models 中覆盖它.

您需要做的就是设置 recipient_idsender_id , 我们在 create方法:
def create
@message = current_user.message.new message_params
@message.recipient_id = @recipient.id
@message.save
end

你在这里做了一些非常聪明的事情。

首先,您已隐式设置 sender_id外键调用 current_user.messages .如果您调用 Message.new ,这将是一个完全不同的故事(必须设置 sender_id )

其次,因为您使用的是嵌套路由,所以您可以使用 @recipient您在 before_action 中设置的变量方法给我们 id对于 recipient_id .

这应该适合你。您不需要使用 inverse_of除非您尝试访问子/嵌套模型中的“父”模型数据。

建议

你在做什么是完全有效的

核心技巧是确保您的 Message模型完全独立于您的 User .这是通过您的设置实现的,允许您创建所需的各种对象。

您需要考虑的另一个方面是您将如何确保您能够为用户提供拥有 "threaded" messages 的能力。 .您将使用其中一个层次结构 gem 来实现此目的, Ancestry Closure_Tree

添加此功能将更加深入。如果您需要,我可以提供信息(只需发表评论)

线程

层次 gem 实际上使用起来相对简单。

“处理”您的消息的技巧是使用这些 gem 之一( AncestryClosure_Tree),因为它们为您提供了您可以调用您的项目的“方法”。它们通过在您的数据库中创建多个列来工作,并在您保存/创建所需的对象时填充它们

“线程”问题是一个大问题,因为没有“层次结构” gem ,您将无法调用所需记录的“子”对象,从而阻止线程发生。这是 good Railscast关于如何实现它:

enter image description here

诀窍是使用名为 "recursion" 的东西。

递归是您创建“无限”循环的地方,就数据的“递归”程度而言。例如,如果您有一个带有子对象的对象,则必须循环遍历子对象,然后递归地遍历这些子对象的子对象,直到达到显示所有数据的程度:

Recursion is the process of repeating items in a self-similar way. For instance, when the surfaces of two mirrors are exactly parallel with each other, the nested images that occur are a form of infinite recursion.



因此,您可以这样做:

  1. Make sure you save your objects with the correct parents
  2. To display the "threaded" conversation, loop through those parents
  3. Use recursion to loop through their children


我们使用 ancestry gem,它存储层次结构与 closure_tree 略有不同此后我们发现的 gem(打算很快使用闭包树 gem)。

因此,您首先必须自己保存任何层次结构:

enter image description here

这将允许您保存该对象的各种“ parent ”。这意味着当您加载对象并希望在其后代中循环时,您将能够使用 Ancestry object methods :

enter image description here

这意味着您将能够使用以下内容:
#app/views/comments/index.html.erb
<%= render partial: "comments", locals: { collection: @comments } %>

#app/comments/_comments.html.erb
<% collection.arrange.each do |comment, sub_item| %>
<%= link_to comment.title, comment_path(comment) %>

<% if category.has_children? %>
<%= render partial: "category", locals: { collection: category.children } %>
<% end %>
<% end %>

关于ruby-on-rails - Rails 用户到用户消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25752438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com