Creating multiple resources in a single RESTful PO

2019-03-18 15:23发布

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.

2条回答
淡お忘
2楼-- · 2019-03-18 15:38

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.

查看更多
虎瘦雄心在
3楼-- · 2019-03-18 15:58

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.

查看更多
登录 后发表回答