Rails多态发布视图中的关联和form_for

时间:2014-10-20 04:02:38

标签: ruby-on-rails forms views posts polymorphism

我在部门视图中为多态“部门”帖子设置表单时遇到了问题。我按照rails-cast教程进行了多态关联here

型号:

   class Course < ActiveRecord::Base
        belongs_to :department, inverse_of: :courses
        has_and_belongs_to_many :users, -> { uniq }
        has_many :posts, as: :postable  #allows polymorphic posts
    end
    class Department < ActiveRecord::Base
        has_many :courses, inverse_of: :department
        has_many :posts, as: :postable  #allows polymorphic posts
        has_and_belongs_to_many :users, -> {uniq}
    end
    class Post < ActiveRecord::Base
        belongs_to :user, touch: true #updates the updated_at timestamp whenever post is saved
        belongs_to :postable, polymorphic: true #http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
        belongs_to :department, counter_cache: true #for counting number of posts in department
        belongs_to :course, counter_cache: true
        validates :department_id, :course_id, presence: true
    end

配置/路由

  devise_for :users
  devise_scope :users do
    match '/users/:id',       to: "users#show",    via: 'get'
  end
  resources :departments do
    resources :courses
    resources :posts
  end
  resources :courses do
    resources :posts
  end

视图/部门/ show.html.erb

  <div class="tab-pane" id="posts"><br>
    <center><h3>Posts:</h3></center>
    <%= render "posts/form", postable: @department %>
  </div>

视图/帖/ _form.html.erb

<%= render "posts/wysihtml5" %>
<center><h3>Create New Post:</h3></center>

    <%= form_for [@postable, Post.new] do |f| %>
      <%= f.label :title %>
      <%= f.text_field :title, class: "form-control" %>

      <%= f.label :description %>
      <%= f.text_area :description, :rows => 3, class: "form-control" %>

      <%= f.text_area :content, :rows => 5, placeholder: 'Enter Content Here', class: "wysihtml5" %>

      <span class="pull-left"><%= f.submit "Create Post", class: "btn btn-medium btn-primary" %></span>
   <% end %>

控制器/ post_controller.rb

class PostsController < ApplicationController
    before_filter :find_postable
    load_and_authorize_resource 

    def new
        @postable = find_postable
        @post = @postable.posts.new
    end

    def create
        @postable = find_postable
        @post = @postable.posts.build(post_params)

        if @post.save
            flash[:success] = "#{@post.title} was sucessfully created!"
            redirect_to department_post_path#id: nil        #redirects back to the current index action
        else
            render action: 'new'
        end
    end

    def show
        @post = Post.find(params[:id])
    end

    def index
        @postable = find_postable
        @posts = @postable.posts
    end
...
    private
    def post_params
        params.require(:post).permit(:title, :description, :content)
    end

    def find_postable   #gets the type of post to create
        params.each do |name, value|
            if name =~ /(.+)_id$/
                return $1.classify.constantize.find(value)
            end
        end
        nil
    end

控制器/ departments_controller.rb

def show
    id = params[:id]
    @department = Department.find(id)

    @course = Course.new
    @course.department_id = @department
end

错误是“#&lt;#:0x0000010d1dab10&gt;”的未定义方法`posts_path'“

我认为错误与表单中的路径有关,但我不知道是什么。我也试过了[@postable, @postable.posts.build],但这只是给了我未定义的方法:PostsController

有人知道发生了什么以及如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

@department作为本地变量传递给部分表单,但表单调用实例变量

# views/departments/show.html.erb
<%= render "posts/form", postable: @department %> # <------ postable

# views/posts/_form.html.erb
<%= form_for [@postable, Post.new] do |f| %>      # <------ @postable

因此,未正确确定命名空间路由

[@postable, Post.new]  # => departments_posts_path
[   nil   , Post.new]  # => posts_path

检查您的路线,只能通过嵌套路线访问帖子。 posts_path不是有效路线,它的方法不存在,且错误是正确的:未定义方法`posts_path&#39;


修正:

在departments控制器中设置@postable实例变量,以便表单助手可以使用它:

def show
    id = params[:id]
    @postable, @department = Department.find(id)  # <-- add @postable

    @course = Course.new
    @course.department_id = @department
end

然后你只需在视图中调用render:

<%= render "posts/form" %>