0

我想通过构建一个网站来学习Ruby on Rails。用户可以添加内容:帖子和图片。帖子和图片可以有一个或多个标签。我希望每个关系都是HABTM,这样我就可以通过特定的标签轻松访问帖子,图片,反之亦然。窗体为两个HABTM关系中的对象,Rails 3

我正在尝试将表单添加到帖子和图片的标签。当我提交任何形式,我得到的错误是:

POST http://localhost:8080/post/1/tags 500 (Internal Server Error)

当我看到返回的对象(这是两种形式相同):

未定义的方法`POST_ID”为#Tag id:nil,name:“asdf”>上线'@ tag.save'

我已经尝试添加post_id,picture_id到Tag的attr_accesible;没有骰子。 感谢您的帮助!我觉得我只是缺少一些小东西。

我的模型:

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 
+0

post_idpicture_id属性请运行'耙routes',给我们增加了输出 – weltschmerz 2013-02-13 20:02:32

+0

耙路线在问题的底部。 – deakolt 2013-02-13 20:14:06

回答

1

的问题是

validates :name, :uniqueness => { :sscope => :post_id } 
    validates :name, :uniqueness => { :scope => :picture_id } 

,因为这些方法需要tag模式对存储在posts_tags

+0

非常感谢。有了这种理解,似乎没有办法使用内置的Rails验证来进行这种验证?我会写一个自定义验证 - – deakolt 2013-02-13 21:59:38

1

看一看运行rake routes进行输出的路线。有这一行:

post_tags POST /posts/:id/tags(.:format) tags#tag_post 

这表明你该路径必须是posts(复数),而不是post(单数)。

所以,你应该将张贴到

/posts/1/tags 

顺便说一句,我知道你说你正在学习Rails的,所以它的伟大,你是从头开始建立一个标签系统 - 但后来你可能希望有看看这个真棒宝石acts as taggable on。这是超级简单和乐趣。这是一个rails casts,非常好地覆盖标签。

+0

谢谢!虽然这不是直接的问题,但我的代码仍然是一个问题,我删除了。谢谢!!并感谢您对'作为标签的行为'的建议,我看到那个宝石,但像你说的那样认为从头开始实施标签将是一个有用的学习设备:) – deakolt 2013-02-13 22:00:21