创建 "many-to-many" 关系的问题
Issues with creating a "many-to-many" relation
我想做一个简单的任务:我创建了一个 "magazine" 脚手架,但我希望它有一个特定的关系:用户可以参与杂志的创建/编辑,并且创建一本杂志可能需要多个用户。
我检查了 APIDock 并执行了以下操作:
- 指定杂志与用户的关系
model/magazine.rb
class Magazine < ApplicationRecord
mount_uploader :thumbnail, ThumbnailUploader
has_and_belongs_to_many :users
end
model/user.rb
class User < ApplicationRecord
has_and_belongs_to_many :magazines
# More code...
end
创建迁移以将 table 添加到 link 两个模型
class ManyToMany < ActiveRecord::Migration[5.0]
def change
create_table :magaziness_users, :id => false do |t|
t.integer :user_id
t.integer :magazine_id
end
add_index :magazines_users, [:magazine_id, :user_id]
end
end
然后我运行迁移
添加了曾经记录到数据库的所有用户的列表以创建下拉列表
<div class="field">
<%= f.label :users %>
<%= f.select :users, User.all_except(current_user).collect {|u| [u.username, u]}, {prompt: 'Add a creator?'}, { :multiple => true, :size => 3 } %>
</div>
但是,当我保存一本新杂志时,用户并没有被保存,并且“magazines_user 仍然是空的。
编辑 1
这是一个自动生成的控制器,因为我使用脚手架命令来创建它。除了 set_magazine
函数,我没有触及任何东西,我在其中添加了 Friendly_Id
class MagazinesController < ApplicationController
before_action :set_magazine, only: [:show, :edit, :update, :destroy]
def index
@magazines = magazine.all
end
def show
end
def new
@magazine = magazine.new
end
def edit
end
def create
@magazine = magazine.new(magazine_params)
if @magazine.save
redirect_to @magazine, notice: 'magazine was successfully created.'
else
render :new
end
end
def update
if @magazine.update(magazine_params)
redirect_to @magazine, notice: 'magazine was successfully updated.'
else
render :edit
end
end
def destroy
@magazine.destroy
redirect_to magazines_url, notice: 'magazine was successfully destroyed.'
end
private
def set_magazine
@magazine = magazine.friendly.find(params[:id])
end
def magazine_params
params.require(:magazine).permit(:titre, :description, :apercu, :users)
end
end
我是不是忘记了什么步骤?
所以这是我的代码工作的答案:
我做了两个脚手架:
rails generate scaffold user username:string email:uniq password:digest
rails generate scaffold magazine title:string description:text preview:string
然后将此添加到杂志迁移中:
create_table :magazines_users, id: false do |t|
t.belongs_to :magazine, index: true
t.belongs_to :user, index: true
end
在我的表单中,我添加了:
<div class="field">
<%= f.label :users %>
<%= f.select :user_ids, User.all.collect { |u| [u.username, u.id] }, {include_blank: true}, {multiple: true} %>
</div>
而在我的杂志控制器中,我只修改了 magazine_params:
def magazine_params
params.require(:magazine).permit(:title, :description, :preview, :user_ids => [])
end
为了看到它有效,我在杂志展示视图中添加了这个:
<p>
<strong>Users:</strong>
<%= @magazine.users.map(&:username).join(" - ") %>
</p>
当然,我添加了 "has_and_belongs_to_many",就像您在 User 和 Magazine 模型中所做的那样。
就是这样:)
使用 Rails 5 进行测试,效果很好。 :)
另外我强烈建议你看看the simple_form gem。它有一些很好的方法来轻松处理关联(如 has_and_belongs_to_many),像这样:<%= f.association :users, collection: User.all_except(current_user).order(:username) %>
我想做一个简单的任务:我创建了一个 "magazine" 脚手架,但我希望它有一个特定的关系:用户可以参与杂志的创建/编辑,并且创建一本杂志可能需要多个用户。
我检查了 APIDock 并执行了以下操作:
- 指定杂志与用户的关系
model/magazine.rb
class Magazine < ApplicationRecord
mount_uploader :thumbnail, ThumbnailUploader
has_and_belongs_to_many :users
end
model/user.rb
class User < ApplicationRecord
has_and_belongs_to_many :magazines
# More code...
end
创建迁移以将 table 添加到 link 两个模型
class ManyToMany < ActiveRecord::Migration[5.0] def change create_table :magaziness_users, :id => false do |t| t.integer :user_id t.integer :magazine_id end add_index :magazines_users, [:magazine_id, :user_id] end end
然后我运行迁移
添加了曾经记录到数据库的所有用户的列表以创建下拉列表
<div class="field"> <%= f.label :users %> <%= f.select :users, User.all_except(current_user).collect {|u| [u.username, u]}, {prompt: 'Add a creator?'}, { :multiple => true, :size => 3 } %> </div>
但是,当我保存一本新杂志时,用户并没有被保存,并且“magazines_user 仍然是空的。
编辑 1
这是一个自动生成的控制器,因为我使用脚手架命令来创建它。除了 set_magazine
函数,我没有触及任何东西,我在其中添加了 Friendly_Id
class MagazinesController < ApplicationController
before_action :set_magazine, only: [:show, :edit, :update, :destroy]
def index
@magazines = magazine.all
end
def show
end
def new
@magazine = magazine.new
end
def edit
end
def create
@magazine = magazine.new(magazine_params)
if @magazine.save
redirect_to @magazine, notice: 'magazine was successfully created.'
else
render :new
end
end
def update
if @magazine.update(magazine_params)
redirect_to @magazine, notice: 'magazine was successfully updated.'
else
render :edit
end
end
def destroy
@magazine.destroy
redirect_to magazines_url, notice: 'magazine was successfully destroyed.'
end
private
def set_magazine
@magazine = magazine.friendly.find(params[:id])
end
def magazine_params
params.require(:magazine).permit(:titre, :description, :apercu, :users)
end
end
我是不是忘记了什么步骤?
所以这是我的代码工作的答案:
我做了两个脚手架:
rails generate scaffold user username:string email:uniq password:digest
rails generate scaffold magazine title:string description:text preview:string
然后将此添加到杂志迁移中:
create_table :magazines_users, id: false do |t|
t.belongs_to :magazine, index: true
t.belongs_to :user, index: true
end
在我的表单中,我添加了:
<div class="field">
<%= f.label :users %>
<%= f.select :user_ids, User.all.collect { |u| [u.username, u.id] }, {include_blank: true}, {multiple: true} %>
</div>
而在我的杂志控制器中,我只修改了 magazine_params:
def magazine_params
params.require(:magazine).permit(:title, :description, :preview, :user_ids => [])
end
为了看到它有效,我在杂志展示视图中添加了这个:
<p>
<strong>Users:</strong>
<%= @magazine.users.map(&:username).join(" - ") %>
</p>
当然,我添加了 "has_and_belongs_to_many",就像您在 User 和 Magazine 模型中所做的那样。
就是这样:) 使用 Rails 5 进行测试,效果很好。 :)
另外我强烈建议你看看the simple_form gem。它有一些很好的方法来轻松处理关联(如 has_and_belongs_to_many),像这样:<%= f.association :users, collection: User.all_except(current_user).order(:username) %>