Rails将params传递给不同的模型然后保存它不工作

时间:2016-02-03 07:04:42

标签: ruby-on-rails

我有一个'帖子'控制器,我有两个变量标题和正文,我通过强参数。但我需要使用另外两个变量,即路径和名称不同的型号名称'文件'..而且我也在保存数据库中的内容..但无法这样做..注意此错误视图[posts / _form.html.erb]
的未定义方法`name'
[posts_controller]

class PostsController < ApplicationController
    before_action :authenticate_user! 

    def index
        @posts = Post.user_post(current_user).order('created_at DESC').paginate(:page => params[:page], :per_page => 5)

    end 

    def new
        @post = Post.new

    end

    def show
        @post = find_params
    end

    def create

        @post = Post.create(post_params)

        @post.user = current_user


        if @post.save
            redirect_to @post
        else
            render 'new'
        end
    end

    def edit
        @post = find_params
    end

    def update
        @post = find_params

        if @post.update(post_params)
            redirect_to @post
        else
            render 'edit'
        end
    end

    def destroy
        @post = find_params
        @post.destroy

        redirect_to posts_path
    end

    private

    def post_params

        params.require(:post).permit(:title, :body)
        Document.new(params,:files=>[])
    end

    def find_params
        Post.find(params[:id])
    end


end


[交/ _form.html.erb]

<%= form_for @post,html: { multipart: true } do |f| %>
    <% if @post.errors.any? %>
        <div id="errors">
            <h2><%= pluralize(@post.errors.count, "error") %> prevented this post from saving:</h2>
            <ul>
                <% @post.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>
    <%= f.label :title %><br>
    <%= f.text_field :title %><br>
    <br>
    <%= f.label :body %><br>
    <%= f.text_field :body %><br>
    <br>
        <%= f.label :name %> <br>
        <%= f.text_field :name %><br>
    <br>

    <br>
    <%= f.label :path %><br>
    <%= f.file_field :path %><br>


    <%= f.submit %>
<% end %>


[document.rb]

class Document < ActiveRecord::Base

    validates :name, presence: true
    validates :path, presence: true
    validates :resource_type, presence: true
    validates :resource_id, presence: true

    mount_uploader :path, PathUploader 
    validates :name, presence: true 

    # def self.abc
    #   params.permit(:name,:path)
    # end
    def initialize(params,file)
        params=file[:name]  
        #params.permit(name =>:name,path =>:path)

    end

end

2 个答案:

答案 0 :(得分:1)

因此模型上的undefined method表明模型上不存在该方法。想看模特的方法吗? Post.methods。但是,在此示例中,未在模型上定义列name,并且您试图告诉Post它有name。您需要做的是nest您的参数。

虽然有大量的清理工作可能需要先关注,但您的答案可以在accepts_nestable_attributes_for类方法中找到,如此处所示,http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html和strong_params文档,如下所示, http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

在您的情况下,您想要从帖子创建新文档。你允许的params hash看起来像这样,

params.require(:post).permit(:title, :body, :document_attributes => [:name])

确保document_attributes是单数;如果一个人有很多宠物(例如),那么你就有了pets_attributes。

在你的形式中,经常绊倒人的是建设者。

<%= form_for @post do |f| %>
<%= f.text_field :title %>
<%= f.text_field :body %>

<%= f.fields_for @post.document do |document_field| %>
<%= document_field.text_field :name %>
<% end %>

<%= f.submit %>
<% end %>

确保您告诉ERB <%= f.fields_for %>,而不只是<% f.fields_for %>

答案 1 :(得分:1)

  

的未定义方法`name'

您引用了Post表单的不存在的属性

<%= form_for @post,html: { multipart: true } do |f| %>

    <%= f.label :title %><br>
    <%= f.text_field :title %><br>
    <br>
    <%= f.label :body %><br>
    <%= f.text_field :body %><br>

    <%= f.submit %>
<% end %>

删除:name&amp; :path引用。

-

如果您想将“额外”属性传递给其他模型,则需要使用accepts_nested_attributes_for 将params分别设置为“主要”模型:

#app/models/post.rb
class Post < ActiveRecord::Base
   has_many :documents
   accepts_nested_attributes_for :documents
end

#app/models/document.rb
class Document < ActiveRecord::Base
   belongs_to :post
end

这样您就可以将documents作为Post模型的“嵌套”属性传递:

#app/controllers/posts_controller.rb
class PostsController < ApplicationController
   def new
      @post = Post.new
      @post.documents.build
   end

   def create
      @post = Post.new post_params
      @post.save
   end

   private

   def post_params
      params.require(:post).permit(:title, :body, documents_attributes: [:name, :path])
   end
end

#app/views/posts/_form.html.erb
<%= form_for @post do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area  :body  %>
  <%= f.fields_for :documents do |d| %>
     <%= d.text_field :name %>
     <%= d.text_field :path %>
  <% end %>
  <%= f.submit %>
<% end %>