保存依赖于两个表的记录
Saving a record that relies on two tables
正在开发我的第一个 rails 应用程序。
我有两个模型:专辑和曲目。
将曲目添加到专辑时,我需要专辑 ID 才能保存。
我有一个 collection_select 可以提取所有相册并按降序列出它们的 ID:
<%= form.collection_select :albums_id, Album.all.order(id: :desc), :id, :title, :include_blank => false %>
这很好用,创建了 html:
<select name="track[albums_id]" id="track_albums_id">
<option value="11">Eleventh Album Title</option>
<option value="10">Tenth Album Title</option>
...
</select>
但是当我尝试保存新记录时,我总是得到错误:
Album must exist
控制器有:
def create
@track = Track.new(track_params)
respond_to do |format|
if @track.save
format.html { redirect_to @track, notice: 'Track added.' }
format.json { render :show, status: :created, location: @track }
else
@page_title = 'ERROR - Add Track'
format.html { render :new }
format.json { render json: @track.errors, status: :unprocessable_entity }
end
end
end
和track_params
指的是:
private
def track_params
params.require(:track).permit(:albums_id, :title, :track_number, :track_url)
end
型号:
album.rb
class Album < ApplicationRecord
has_many :tracks
validates :title, presence: true
validates :release_year, presence: true
has_one_attached :photo
end
track.rb
class Track < ApplicationRecord
belongs_to :album
validates :title, presence: true
validates :track_number, presence: true
validates :track_url, presence: true
end
routes.rb
Rails.application.routes.draw do
resources :tracks
root 'pages#about'
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
get 'contact', to: 'messages#new', as: 'contact'
get 'sessions', to: 'sessions#new'
get 'dashboard', to: 'pages#dashboard', as: 'dashboard'
resources :videos
resources :gigs
resources :photos
resources :albums
resources :users
resources :groups
resources :messages
resources :sessions, only: [:new, :create, :destroy]
post "/delayed_job" => DelayedJobWeb, :anchor => false
end
接受除 :albums_id
以外的所有值。 collection_select 中的所选值始终被忽略并触发阻止保存曲目的错误。
albums_id
是数据库列名,由 rails 作为 belongs_to: albums
.
的结果创建
我哪里做得不好?
更新:迁移
...create_albums.rb:
class CreateAlbums < ActiveRecord::Migration[5.2]
def change
create_table :albums do |t|
t.string :artist
t.string :copyright
t.string :title
t.date :release_year
t.text :comment
t.timestamps
end
end
end
...create_tracks.rb:
class CreateTracks < ActiveRecord::Migration[5.2]
def change
create_table :tracks do |t|
t.belongs_to :albums
t.string :title
t.integer :track_number, :default => 1
t.string :track_url
t.timestamps
end
end
end
您可以做的是遵循 rails 惯例,而不是绕过它。
您可以删除 albums_id 列(有一种方法可以使此工作正常进行,但同样是一种变通方法,但不可取)因此,yiu 可以先删除 albums_id 列,然后添加 album_id 如下所示:
rails g migration DropColumnFromTrack
然后在生成的迁移文件中:
remove_column :tracks, :albums_id
然后执行:(假设您在该列中没有数据)
rails db:migrate
现在生成 album_id 列:
下面 album:references 表示我们告诉曲目 table 中的记录属于专辑 table.
rails g migration AddAlbumToTrack album:references
然后做
rails db:migrate
确保您的曲目中有一个 album_id 列 table,现在关联应该可以正常工作了
正在开发我的第一个 rails 应用程序。 我有两个模型:专辑和曲目。
将曲目添加到专辑时,我需要专辑 ID 才能保存。 我有一个 collection_select 可以提取所有相册并按降序列出它们的 ID:
<%= form.collection_select :albums_id, Album.all.order(id: :desc), :id, :title, :include_blank => false %>
这很好用,创建了 html:
<select name="track[albums_id]" id="track_albums_id">
<option value="11">Eleventh Album Title</option>
<option value="10">Tenth Album Title</option>
...
</select>
但是当我尝试保存新记录时,我总是得到错误:
Album must exist
控制器有:
def create
@track = Track.new(track_params)
respond_to do |format|
if @track.save
format.html { redirect_to @track, notice: 'Track added.' }
format.json { render :show, status: :created, location: @track }
else
@page_title = 'ERROR - Add Track'
format.html { render :new }
format.json { render json: @track.errors, status: :unprocessable_entity }
end
end
end
和track_params
指的是:
private
def track_params
params.require(:track).permit(:albums_id, :title, :track_number, :track_url)
end
型号:
album.rb
class Album < ApplicationRecord
has_many :tracks
validates :title, presence: true
validates :release_year, presence: true
has_one_attached :photo
end
track.rb
class Track < ApplicationRecord
belongs_to :album
validates :title, presence: true
validates :track_number, presence: true
validates :track_url, presence: true
end
routes.rb
Rails.application.routes.draw do
resources :tracks
root 'pages#about'
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
get 'contact', to: 'messages#new', as: 'contact'
get 'sessions', to: 'sessions#new'
get 'dashboard', to: 'pages#dashboard', as: 'dashboard'
resources :videos
resources :gigs
resources :photos
resources :albums
resources :users
resources :groups
resources :messages
resources :sessions, only: [:new, :create, :destroy]
post "/delayed_job" => DelayedJobWeb, :anchor => false
end
接受除 :albums_id
以外的所有值。 collection_select 中的所选值始终被忽略并触发阻止保存曲目的错误。
albums_id
是数据库列名,由 rails 作为 belongs_to: albums
.
我哪里做得不好?
更新:迁移
...create_albums.rb:
class CreateAlbums < ActiveRecord::Migration[5.2]
def change
create_table :albums do |t|
t.string :artist
t.string :copyright
t.string :title
t.date :release_year
t.text :comment
t.timestamps
end
end
end
...create_tracks.rb:
class CreateTracks < ActiveRecord::Migration[5.2]
def change
create_table :tracks do |t|
t.belongs_to :albums
t.string :title
t.integer :track_number, :default => 1
t.string :track_url
t.timestamps
end
end
end
您可以做的是遵循 rails 惯例,而不是绕过它。 您可以删除 albums_id 列(有一种方法可以使此工作正常进行,但同样是一种变通方法,但不可取)因此,yiu 可以先删除 albums_id 列,然后添加 album_id 如下所示:
rails g migration DropColumnFromTrack
然后在生成的迁移文件中:
remove_column :tracks, :albums_id
然后执行:(假设您在该列中没有数据)
rails db:migrate
现在生成 album_id 列: 下面 album:references 表示我们告诉曲目 table 中的记录属于专辑 table.
rails g migration AddAlbumToTrack album:references
然后做
rails db:migrate
确保您的曲目中有一个 album_id 列 table,现在关联应该可以正常工作了