如何创建新的嵌套资源?
问题描述:
用户可以通过歌曲和电影表拥有许多收藏夹top_songs,top_movies。 用户注册用户(current_user)想要发布他的最爱电影和歌曲。如何创建新的嵌套资源?
也许所有模型关联都是正确的,我卡在控制器和视图(窗体)中。
当我提出,我得到错误 -
不能大规模指派保护的属性:歌曲
我怎么能做到这一点吗?所有的代码都在下面。
用户模型
class User < ActiveRecord::Base
attr_accessible :id, :name_special_char, :screenname, :fullname, :username, :prefix, :firstname, :lastname,:middlename, :suffix, :age, :sex, :email,
:top_movies_attributes,:top_songs_attributes
has_many :top_movies
has_many :movies, through: :top_movies
has_many :top_songs
has_many :songs, through: :top_songs
accepts_nested_attributes_for :top_songs, :allow_destroy => true
accepts_nested_attributes_for :top_movies, :allow_destroy => true
end
电影模型
class Movie < ActiveRecord::Base
attr_accessible :name
has_many :top_movies
has_many :users, through: :top_movies
end
TopMovie模型
class TopMovie < ActiveRecord::Base
belongs_to :user
belongs_to :movie
# attr_accessible :title, :body
end
宋模型
class Song < ActiveRecord::Base
attr_accessible :name
has_many :top_songs
has_many :users, through: :top_songs
end
TopSong模型
class TopSong < ActiveRecord::Base
belongs_to :user
belongs_to :song
# attr_accessible :title, :body
end
控制器
class MyTopFivesController < ApplicationController
def new
@favorites = current_user
@[email protected]()
@[email protected]()
respond_to do |format|
format.html # new.html.erb
format.json { render json: @useraccounts_my_top_fife }
end
end
def create
@favorites = current_user(params[:user])
@favorites.save!
# Here i have stuck. i am not sure how to save.
end
视图形式
<%=nested_form_for @favorites ,:url=>favorites_path(@favorites),:method=>'post' do |f| %>
<label >Songs</label>
<%= f.fields_for :songs do |songs| %>
<div id="Topsongs" >
<div class="input-control text span5 place-left ">
<%= songs.text_field :name,:placeholder=>"songs name.." %>
</div>
<div class="span1 place-left">
<%= songs.link_to_remove "", :class=>"icon-minus" %>
</div>
</div>
<% end %>
<span >
<%= f.link_to_add "", :songs, :class=>"icon-plus", :data => { :target => "#Topsongs" } %>
</span>
<label >movies</label>
<%= f.fields_for :movies do |movies| %>
<div id="Topmovies">
<div class="input-control text span5 place-left ">
<%= movies.text_field :name,:placeholder=>"movies name.." %>
</div>
<div class="span1 place-left">
<%= movies.link_to_remove "", :class=>"icon-minus" %>
</div>
</div>
<% end %>
<span>
<%= f.link_to_add "", :movies, :class=>"icon-plus",:style=>"font-size: 14px;", :data => { :target => "#Topmovies" } %>
</span>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
答
这里有两种设置关联的选项。通过为顶级歌曲和顶级电影创建两个连接模型,您可以使用它。和其他,使用多态关联。
让我们使用多态关联。我们将使用用户,电影,歌曲和最喜欢的模型这个东西。 Favorite模型将包含多态字段。
User.rb
class User < ActiveRecord::Base
attr_accessible :id, :name_special_char, :screenname, :fullname, :username, :prefix, :firstname, :lastname,:middlename, :suffix, :age, :sex, :email
has_many :favourites
has_many :movies, through: :favourites, source: :favouritable, source_type: 'Movie'
has_many :songs, through: :favourites, source: :favouritable, source_type: 'Song'
end
Movie.rb
class Movie < ActiveRecord::Base
attr_accessible :name
has_many :favourites, as: :favouritable
has_many :users, through: :favourites
end
Song.rb
class Song < ActiveRecord::Base
attr_accessible :name
has_many :favourites, as: :favouritable
has_many :users, through: :favourites
end
喜爱。RB
class Favourite < ActiveRecord::Base
belongs_to :users
belongs_to :favouritable, polymorphic: true
end
我们还需要创造新模式“收藏”的迁移。截至目前,我们只需要3列,即。 user_id, favouritable_id, favouritable_type
。这里favouritable_type和favouritable_id是多态字段。 favouritable_type
是一个字符串,favouritable_id
是引用类型。
迁移文件
class CreateFavourites < ActiveRecord::Migration
def change
create_table :favourites do |t|
t.integer :user_id
t.references :favouritable, polymorphic: true
t.timestamps
end
end
end
现在,我们要纪念的一些电影和歌曲是最喜欢的一个用户,那么我们可以将代码在UsersController建设中的数据,而不是创建另一个控制器或我们也可以为Favourites
创建一个控制器。我将在这里使用UsersController
。我正在使用更新操作来更新收藏夹,因为我们在这里不需要任何额外的功能。如果你愿意,你可以添加一个新的动作。
在UsersController.rb
def edit_favourites #or some generic name
@user = current_user.includes(:movies, :songs)
@movies = Movie.all
@songs = Song.all
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
redirect_to users_path #user index page
else
if params[:user][:movie_ids].present? or params[:user][:song_ids].present?
render :edit_favourites
else
render :edit
end
end
end
edit_favourites.html.erb
<%= form_for(@user) do |f| %>
<div class="fields">
<%= f.label :movie_ids, "Favourite Movies: " %>
<%= f.collection_select :movie_ids, @movies, :id, :name, {}, multiple: true %>
</div>
<div class="fields">
<%= f.label :song_ids, "Favourite Songs: " %>
<%= f.collection_select :song_ids, @songs, :id, :name, {}, multiple: true %>
</div>
<% end %>
此外,添加新的行动路线。
谢谢@Manoj Mong。 – Gagan