大家好,我正在开发一个设计用户注册并登录的应用程序,一旦用户登录,他们就可以“创建团队”或“加入团队”。我已经建立了这样的关联
user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
validates_presence_of :phone, :city, :state, :street, :zip, presence: true, on: :create
belongs_to :team
end
team.rb
class Team < ApplicationRecord
has_many :users
end
我的桌子已经建立
schema.rb
create_table "teams", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "team_name"
end
create_table "users", force: :cascade do |t|
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.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "firstname"
t.integer "team_id"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
team_controller.rb
class TeamController < ApplicationController
before_action :authenticate_user!
def index
@team = current_user.team
end
def new_team
end
def create_team
@team = current_user.create_team(sanitize_team)
if @team.save
redirect_to team_root_path
else
render json: @team.errors.full_messages
end
end
def join_team
@teams = Team.all
end
def team
end
private
def sanitize_team
params.require(:team).permit(:team_name, :team_statement)
end
end
我希望用户的“ team_id”属性在创建团队时使用团队ID更新。或他们加入团队时。我的关联正确吗?我将如何在控制器中做到这一点?
答案 0 :(得分:1)
是的,关联是正确的。您只能通过将外键添加到数据库架构中来做得更好。可以由生成器rails g migration AddTeamToUsers team:references
有关关联的更多信息,请参见:https://guides.rubyonrails.org/association_basics.html
在控制器中,您只需要更改白名单参数即可允许team_id
。您可能需要在表单中添加如下所示的视图:
<%= f.select :team_id, Team.all.map { |t| [t.team_name, t.id] } %>
答案 1 :(得分:1)
让您的代码示例降至最低要求:
# app/models/team.rb
class Team < ApplicationRecord
has_many :users
end
# app/models/user.rb
class User < ApplicationRecord
belongs_to :team
end
# db/migrate/20181124230131_create_teams.rb
class CreateTeams < ActiveRecord::Migration[5.2]
def change
create_table :teams do |t|
t.string :team_name
t.timestamps
end
end
end
# db/migrate/20181124230136_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
t.belongs_to :team
t.timestamps
end
end
end
然后在您的控制器中:
team = Team.where(team_name: 'foo').first_or_create!
team.users << current_user
答案 2 :(得分:0)
首先将关联设置为可选:
class User < ApplicationController
belongs_to :team, optional: true
end
否则,对用户模型的验证将不允许没有团队的情况下保存用户。
然后设置团队资源:
# config/routes.rb
resources :teams do
post :join
end
post :join
创建一条附加的POST /teams/:team_id/join
路由。
然后设置控制器:
class TeamsController
# ...
# GET /teams/new
def new
@team = Team.find
end
# POST /teams
def create
@team = Team.new(team_params)
if @team.save
unless current_user.team
current_user.update(team: @team)
end
redirect_to 'somewhere'
else
render :new
end
end
# ...
def join
@team = Team.find(params[:team_id])
if current_user.update(team: @team)
redirect_to @team, notice: 'Team joined'
else
redirect_to @team, error: 'Could not join team'
end
end
#
private
def team_params
params.require(:team).permit(:team_name, :team_statement)
end
end
请注意,不需要为动作名称添加前缀,也无需与“路线方式”兼容。前缀列名称在很大程度上也是多余的。