我正试图通过建立一个网站来学习RubyonRails。用户可以添加内容:文章和图片。帖子和图片可以有一个或多个标签。我希望每一段关系都是HABTM,这样我就可以通过特定的标签轻松访问帖子和图片,反之亦然。
我正在尝试制作表格,为帖子和图片添加标签。当我提交任一表格时,我得到的错误是:
POST http://localhost:8080/post/1/tags 500 (Internal Server Error)
当我查看返回的对象时(这对两种形式都是一样的):
#Tag-id:nil,名称:"asdf">在'@Tag.save'行上的未定义方法`post_id'
我已经尝试将post_id、picture_id添加到Tag的attr_acceptable中;没有骰子。谢谢你的帮助!我觉得我只是缺少了一些小东西。
我的型号:
class Tag < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :pictures
has_and_belongs_to_many :posts
validates :name, :presence => true
validates :name, :uniqueness => { :scope => :post_id }
validates :name, :uniqueness => { :scope => :picture_id }
end
class Post < ActiveRecord::Base
attr_accessible :content, :title
belongs_to :user
has_and_belongs_to_many :tags
end
class Picture < ActiveRecord::Base
attr_accessible :image, :name
belongs_to :user
has_and_belongs_to_many :tags
end
迁移:
class CreateTags < ActiveRecord::Migration
def change
create_table :tags do |t|
t.string :name
end
create_table :pictures_tags, :id => false do |t|
t.references :picture, :tag
end
end
end
class CreatePostsTags < ActiveRecord::Migration
def change
create_table :posts_tags, :id => false do |t|
t.references :post, :tag
end
end
end
在我看来:
<%= form_for([@post, @post.tags.build]) do |f| %>
<%= f.label 'tag' %>
<%= f.text_area :name %>
<%= f.submit %>
<% end %>
<% current_user.pictures.each do |p|
<%= form_for([p, p.tags.build], :remote => true) do |f| %>
<%= f.text_area :name %>
<%= f.submit 'add tag' %>
<% end %>
<% end %>
在我的TagsController:中
def tag_post
authenticate_user!
@post = Post.find(params[:id])
@tag = @post.tags.build(params[:tag])
@tag.save
redirect_to edit_post_path(@post)
end
def tag_picture
authenticate_user!
@picture = Picture.find(params[:id])
@tag = @state.picture.build(params[:tag])
@tag.save
redirect_to edit_picture_path(@picture)
end
Routes.rb:
post '/posts/:id/tags' => 'tags#tag_post', :as => :tag_post
post '/flow/:id/tags' => 'tags#tag_picture', :as => :tag_picture
耙路:
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / flow#flow
root / flow#home
posts_index GET /ramblin(.:format) posts#index
post_tags POST /posts/:id/tags(.:format) tags#tag_post
picture_tags POST /flow/:id/tags(.:format) tags#tag_picture
create_picture POST /flow(.:format) pictures#create
search POST /flow/search(.:format) flow#flow
问题在中
validates :name, :uniqueness => { :sscope => :post_id }
validates :name, :uniqueness => { :scope => :picture_id }
因为这些方法期望tag
模型具有存储在posts_tags
中的post_id
和picture_id
属性
查看通过运行rake routes
输出的路由。有这样一行:
post_tags POST /posts/:id/tags(.:format) tags#tag_post
这表明路径必须是posts
(复数)而不是post
(单数)。
所以,你应该改为张贴到
/posts/1/tags
顺便说一句,我知道你说你正在学习Rails,所以从头开始构建一个标记系统是很好的,但稍后你可能想看看这个可以标记的神奇宝石。它非常简单有趣。这是一个轨道铸件,它很好地越过了标记。