【问题标题】:Strong Parameters in accepts_nested_attributes_for from multiple classes来自多个类的accept_nested_attributes_for 中的强参数
【发布时间】:2014-06-05 08:49:33
【问题描述】:

这可能看起来很长,但不要害怕;) 我的 conversation 控制器的 create 功能有点问题。这是因为使用新的 Rails 4 和其他模型的 强参数 实际上可以被视为一个孩子。目前代码正在运行,但我不确定 strong 参数 的使用是否正确。那么我们来看一下代码:

这是 ConversationMessage 模型

class ConversationMessage < ActiveRecord::Base
      # def change
      #   create_table :conversation_messages do |t|
      #     t.integer :message_id
      #     t.integer :conversation_id
      #   end
      # end

  belongs_to :message, class_name: 'Message', foreign_key: :message_id

  belongs_to :conversation, class_name: 'Conversation', foreign_key: :conversation_id
end

这是 MessageGroupMessage 模型

class MessageGroupMessage < ActiveRecord::Base
    # def change
    #   create_table :message_group_messages do |t|     
    #     t.integer :user_id
    #     t.integer :message_id
    #     t.integer :message_group_id
    #   end
    # end

    belongs_to :user, class_name: 'User', foreign_key: :user_id

    belongs_to :message, class_name: 'Message', foreign_key: :message_id

    belongs_to :message_group, class_name: 'MessageGroup', foreign_key: :message_group_id
end

这里是 MessageGroup 模型

class MessageGroup < ActiveRecord::Base
    # def change
    #   create_table :message_groups do |t|
    #     t.integer :id_user
    #     t.string :message_group_name
    #     t.timestamps
    #   end
    #   add_index :message_groups, :id_user
    # end

    belongs_to :user, class_name: 'User', foreign_key: :id_user

    has_and_belongs_to_many :messages, :join_table => "message_group_messages", class_name: "Message"

    has_many :message_group_messages, class_name: "MessageGroupMessage"
end

这是BodyMessage模型

class BodyMessage < ActiveRecord::Base
    # def change
    #   create_table :body_messages do |t|
    #     t.integer :message_id
    #     t.text :body
    #     t.timestamps
    #   end
    #   add_index :body_messages, :message_id
    # end

    belongs_to :message, class_name: 'Message', foreign_key: :message_id
end

这是消息模型

class Message < ActiveRecord::Base
    # def change
    #   create_table :messages do |t|
    #     t.integer :id_sender
    #     t.integer :id_receiver
    #     t.timestamps
    #   end
    # end

    belongs_to :sender,     class_name: 'User', foreign_key: :id_sender
    belongs_to :receiver,   class_name: 'User', foreign_key: :id_receiver

    has_one :conversation_message, class_name: "ConversationMessage"

    has_one :conversation, through: :conversation_message, source: :conversation

    has_and_belongs_to_many :message_groups, :join_table => "message_group_messages", class_name: "MessageGroup"

    has_many :message_group_messages, class_name: "MessageGroupMessage"

    has_one :body_message, class_name: "BodyMessage"
end

这里是 FoldersConversation 模型

class FoldersConversation < ActiveRecord::Base
    # def change
    #   create_table :folders_conversations do |t|      
    #     t.integer :conversations_folder_id
    #     t.integer :conversation_id
    #   end
    # end

    belongs_to :conversation, class_name: 'Conversation', foreign_key: :conversation_id

    belongs_to :conversations_folder, class_name: 'ConversationsFolder', foreign_key: :conversations_folder_id
end

这里是 ConversationsFolder 模型

class ConversationsFolder < ActiveRecord::Base
    # def change
    #   create_table :conversations_folders do |t|
    #     t.integer :user_id
    #     t.string :folder_name
    #     t.timestamps
    #   end
    #   add_index :conversations_folders, :user_id
    # end

    belongs_to :user,   class_name: 'User', foreign_key: :user_id

    has_and_belongs_to_many :conversations, :join_table => "folders_conversations", class_name: "Conversation"

    has_many :folders_conversations, class_name: 'FoldersConversation'
end

这是 Conversation 模型,其中一个将成为所有其他类的视图,如“childs

class Conversation < ActiveRecord::Base
    # create_table :conversations do |t|        
    #   t.integer :sender_id
    #   t.integer :receiver_id
    #   t.string :subject
    #   t.timestamps
    # end

    belongs_to :sender, class_name: 'User', foreign_key: :sender_id
    belongs_to :receiver,   class_name: 'User', foreign_key: :receiver_id

    has_and_belongs_to_many :conversations_folders, :join_table => "folders_conversations", class_name: "ConversationsFolder"

    has_many :folders_conversations, class_name: 'FoldersConversation'

    has_many :message_group_messages, through: :messages, source: :message_group_messages

    has_many :message_groups, through: :messages, source: :message_groups

    has_and_belongs_to_many :messages, :join_table => "conversation_messages", class_name: "Message"
    accepts_nested_attributes_for :messages, allow_destroy: true

    has_many :body_messages, through: :messages, source: :body_message
    accepts_nested_attributes_for :body_messages, allow_destroy: true

    has_many :conversation_messages, class_name: "ConversationMessage"
    accepts_nested_attributes_for :conversation_messages, allow_destroy: true
end

这里是对话控制器

class ConversationsController < ApplicationController

    def create

        ### GET FROM VIEW -> HERE WHERE THE STRONG PARAMS SHOULD BE WORKING FOR: subject AND body
        @friend = User.friendly.find(params[:id_friend])
        @subject = params[:conversation][:conversation_attributes][:subject]
        @body = params[:conversation][:body_messages]

        @conversation_new = Conversation.new(conversation_params)
        @conversation = @conversation_new.create_new_conversation(current_user, @friend, @subject)

        @message_new = Message.new(message_params)
        @message = @message_new.message_new(current_user, @friend)

        @body_message_new = BodyMessage.new(body_message_params)
        @body_message = @body_message_new.body_message_new(@message, @body)

        @conversation_message_new = ConversationMessage.new(conversation_message_params)
        @conversation_message = @conversation_message_new.conversation_message_new(@conversation, @message)

        folders_conversation = @conversation.add_new_to_folders_conversation(current_user,@friend)

        respond_to do |format|
          format.html { redirect_to conversations_url }
          format.js
        end
    end

    private
        ###
        ### HERE ARE THE STRONG PARAMS
        ###

        def conversation_params
            params.require(:conversation).permit(:subject)
        end 

        ### THESE ARE THE ONES THAT ARE WORKING BUT FOR SURE NOT BY THE CORRECT WAY

        def message_params
            params.require(:conversation).permit(messages_attributes: [:id_receiver])
        end

        def body_message_params     
            params.require(:conversation).permit(body_messages_attributes: [:message_id, :body])
        end

        def conversation_message_params
            params.require(:conversation).permit(conversation_messages_attributes: [:message_id])
        end
    end
end

所有信息都通过 form_for 发送到控制器。这是 Conversation

中的 Create View
<%= form_for(@conversation, url: url_for(controller: 'conversations', action: 'create'), remote: true) do |f|  %>

    SELECT FRIEND
    <%= select_tag :id_friend, options_for_select(@friends.collect{|u| [u.name, u.name]}, {include_blank: 'Select Friend'} ) %>

    <%= f.fields_for :conversation_attributes do |s| %>

        <%= s.label :subject %>
        <%= s.text_field :subject %>                        
    <% end %>

    TITLE TEXT
    <%= f.text_area(:body_messages, cols: 20, rows: 20, value: "") %>

    <%= f.submit "Send", class: "btn btn-large btn-primary" %>
    <%= f.submit "Save in Draft", class: "btn btn-large btn-primary" %>
<% end %>

肯定是我看不到的东西,它让我头晕目眩,却不知道为什么它不起作用。如果我们找到解决方案,它也可能会帮助许多人在 strong 参数也遇到同样的问题

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 strong-parameters


    【解决方案1】:

    这看起来真的很复杂,我先把它简化为处理 1 个nested_attribute set to start

    您的强大参数需要像这样构建

    def conversation_params
      message_attributes = {
        messages_attributes: [:id_receiver]
      }
    
      body_message_attributes = {
        body_messages_attributes: [:message_id, :body]
      }
    
      conversation_messages_attributes = {
        conversation_messages_attributes: [:message_id]
      }
    
      params.require(:conversation).permit(:subject
        message_attributes,
        body_message_attributes,
        conversation_messages_attributes
      )
    end
    

    另外,在您的forms_for @conversation 中,您不需要将那些放在fields_for 下,您可以将关联的has_many 对象放在fields_for

    <%= form_for(@conversation, url: url_for(controller: 'conversations', action: 'create'), remote: true) do |f|  %>
    
      <%= f.text_field :subject %>
    
      <%= f.fields_for :body_messages do |s| %>
        <%= s.text_area(:body, cols: 20, rows: 20, value: "") %>
      <% end %>
    
      # ...
    

    查看指南了解更多信息:http://guides.rubyonrails.org/form_helpers.html#building-complex-forms

    【讨论】:

    • 感谢您的回答,直到今天我才能查看我尝试进行此调整的代码。现在,在我有 conversation = Conversation.new(conversation_params) 的那一行我从控制台收到错误:TypeError(没有将符号隐式转换为整数): .您确定这是创建对象时最好的方法吗?我应该在尚未创建子类的同时传递所有其他参数?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多