Creating multiple resources in a single RESTful PO

2019-03-18 15:02发布

问题:

I'm creating an API in rails to expose to an iPhone app that I'm working on. I understand that usually you only create a single resource when posting to the create action of a controller in Rails. However, I'm not sure the best way to go about creating many resources at once. Is it acceptable to post JSON/XML containing multiple resources to be created of the same type in a single POST?

For example, creating a message and then adding many recipients. There is a model for the message itself, and then a model for a recipients that belongs to the message. I create the message by posting to /messages, but then what if I have 50 recipients to add to that message? Making 50 separate POSTs to /messages/1/recipients seems excessive and wasteful. What is the best way to go about this?

I'm new to Rails and RESTful apps in general and very much appreciate any help.

回答1:

You could use accepts_nested_attributes_for for this. In your parent model – where you define your has_many association – you'd add the accepts_nested_attributes_for giving it the same association name. Much like this:

class Message < ActiveRecord::Base
  has_many :recipients
  accepts_nested_attributes_for :recipients
end

class Recipient < ActiveRecord::Base
  belongs_to :message
end

Then, in your message's form, you'd have a bunch of fields for the recipients named something like message[recipients_attributes][][name] and message[recipients_attributes][][email]. Or you could use form_for and fields_for (you just have to remember to build at least one instance in your has_many collection when you go to the new page).

For more (and better) examples, watch this Railscast.



回答2:

If you are posting XML data, you also need to include type="array". Here's an example:

<message>
  <recipients_attributes type="array">
     <recipient>
       <name>Some Name</name>
       <email>example@example.com</email>
     </recipient>
     <recipient>
       <name>Some Name 2</name>
       <email>example2@example.com</email>
     </recipient>
  <recipients_attributes>
</message>

If you don't, you'll get errors like "undefined method `stringify_keys' for Array" and "can't convert String into Integer" depending on your version of Rails. These originate from active_record/nested_attributes.rb.