2009-11-20 2 views
0

Я пытаюсь создать приятную структуру RESTful для моего приложения в рельсах, но теперь я застрял в концепции, которая, к сожалению, я не уверен если это правильно, но если кто-то может мне помочь, это будет очень хорошо оценено.Rails - RESTful Routing - добавьте POST для члена ie (советы/6)

Если заметил, что для RESTful маршрутов, которые мы имеем (в незакомментированные из них)

collection 
    :index => 'GET' 
    :create => 'POST' 
    #:?  => 'PUT' 
    #:?  => 'DELETE' 

member 
    :show => 'GET' 
    #:?  => 'POST' 
    :update => 'PUT' 
    :destroy => 'DELETE' 

в данном случае я говорю только о действии базового уровня или те, которые происходят непосредственно внутри т.е. http://domain.com/screename/tips или http://domain.com/screename/tips/16

но в то же время я замечаю, что для членов нет возможности POST, кто-нибудь знает почему?

Что делать, если я пытаюсь создать самостоятельный элемент, который клонирует себя с другим onwer?

Я почти уверен, что это было бы хорошо сгенерировано методом POST внутри действия элемента, но, к сожалению, похоже, что на карте отсутствуют методы по умолчанию. Ресурсы на рельсах для этого.

Я пытался что-то с помощью: член, или: новый, но он не работает, как этот

map.resources :tips, :path_prefix => ':user', :member => {:add => :post} 

так что это будет доступ внутрь http://domain.com/screename/tips/16/add и не http://domain.com/screename/tips/16.

Как можно создать метод POST по умолчанию для участника в маршруте RESTful?

Я думал, что, может быть, это не там, потому что это не является частью декларации REST, но быстрый поиск по ней я нашел:

POST

для коллекций: Создайте новую запись в коллекции, где идентификатор автоматически присваивается коллекцией. Созданный идентификатор обычно включается как часть данных, возвращаемых этой операцией.

для членов: Рассматривает адресованный элемент как коллекцию в отдельности и создает новый подчиненный.

Так эта концепция до сих пор такой же, если вы думаете о методе DELETE или PUT для коллекции. Что делать, если я хочу удалить всю коллекцию вместо одного члена? или даже заменить их (PUT)?

Как я могу создать эти конкретные методы, которые, как представляется, отсутствуют на map.resources?

Все, я надеюсь, что это легко понять.

Приветствия

ответ

2

Причина, по которой они не включены, заключается в том, что они опасны до тех пор, пока они не будут защищены. Член POST не так много, как сбор PUT/DELETE. Пропущенный POST-член является скорее случаем, когда он становится излишним с помощью действия POST по умолчанию.

Если вы по-прежнему действительно хотите добавить эти дополнительные действия по умолчанию, единственный способ, которым вы собираетесь это сделать, - это переписать бит ActionController :: Resources.

Однако это не сложно. На самом деле вам нужно только переписать два метода. Даже тогда вам не нужно полностью их переписывать. Биты методов, которые вам нужно добавить к этим методам, на самом деле не связаны с сложной обработкой аргументов для достижения вашей цели. Таким образом, вы можете пройти с помощью простой пары alias_method_chain.

Предполагая, что я не совершил никаких ошибок, в том числе следующие будут создавать дополнительные маршруты по умолчанию, как описано ниже. Но делайте это на свой страх и риск.

module ActionController 
    module Resources 
    def map_member_actions_with_extra_restfulness(map, resource) 
     map_member_actions_without_extra_restfulness(map, resource) 
     route_path = "#{resource.shallow_name_prefix}#{resource.singular}" 
     map_resource_routes(map, resource, :clone, resource.member_path, route_path, :post, :force_id => true) 
    end 

    alias_method_chain :map_member_actions, :extra_restfulness 


    def map_default_collection_actions_with_extra_restfullness(map, resource) 
     map_default_collection_actions_without_extra_restfullness(map,resource 
     index_route_name = "#{resource.name_prefix}#{resource.plural}" 

     if resource.uncountable? 
     index_route_name << "_index" 
     end 

     map_resource_routes(map, resource, :rip, resource.path, index_route_name, :put) 
     map_resource_routes(map, resource, :genocide, resource.path, index_route_name, :delete) 
    end 

    alias_method_chain :map_default_collection_actions, :extra_restfulness 
    end 
end 

Вам придется возиться с генераторами, чтобы гарантировать, что сценарий/генерировать ресурс х создаст содержательные методы для этих новых действий.

Теперь, когда мы рассмотрели практическую часть, давайте поговорим об этой теории. Часть проблемы возникает со словами, чтобы описать недостающие действия:

Действия участника, описанные для POST в вопросе, хотя технически правильные не сохраняются при применении к ActionController и базовому ActiveRecord. В лучшем случае это двусмысленно, в худшем случае это невозможно. Это имеет смысл для ресурсов с рекурсивным характером (например, деревьями) или ресурсами, которые имеют много другого вида ресурсов. однако этот второй случай неоднозначен и уже охвачен Rails. Вместо этого я выбрал клон для сбора POST. Это имело смысл для публикации по умолчанию в существующей записи. Вот остальные действия по умолчанию, я решил на:

collection 
    :index  => 'GET' 
    :create  => 'POST' 
    :rip   => 'PUT' 
    :genocide => 'DELETE' 

member 
    :show => 'GET' 
    :clone => 'POST' 
    :update => 'PUT' 
    :destroy => 'DELETE' 

Я выбрал геноцид для сбора DELETE, потому что это просто звучит правильно. Я выбрал Rip для коллекции PUT, потому что это был термин, с которым я работал, чтобы описать акт клиента, заменяющий все устройства одного поставщика чужого.

+0

Это действительно класс EMFi, я очень ценю это. :) Теперь его гораздо легче понять, так как вы принесли и техническую, и теоретическую стороны ситуации. Я начну думать таким образом, прежде чем строить архитектуру маршрутизации для своих приложений. Спасибо. +1 !!! – zanona

0

Я не совсем следующий, но ответить на ваш последний вопрос есть, вы можете добавить коллекцию маршрутов для update_multiple или destroy_multiple, если вы хотите обновить или удалить несколько записей, а не одной записи одной в время.

Я ответил на этот вопрос ранее сегодня, на самом деле, вы можете найти это here.

Причина, по которой POST для определенного члена не существует, потому что эта запись участника уже существует в базе данных, поэтому единственное, что вы можете с ней сделать, это GET (посмотреть), PUT (update) или DELETE (уничтожить). POST предназначен только для создания новых записей.

Если вы пытались дублировать существующий член, вы хотели бы ПОЛУЧИТЬ исходный элемент в «дублированном» действии члена и POST в корень ресурса с его содержимым.

Пожалуйста, дайте мне знать, если мне не хватает того, что вы просите.

+0

Привет, bensie, спасибо большое, я всегда теряю сосредоточенность на REST, потому что я все время забываю о его существовании с записями базы данных, поэтому мой вопрос состоял в том, как поместить это уничтожение и обновить несколько методов на базовом уровне коллекции as/screename/tips/с PUT или DELETE. являются ли эти специальные имена для использования на базовом уровне? потому что я тестировал, и вам нужно использовать as/screename/tips/destroy_multiple, если вы добавите его как метод сбора. поэтому, чтобы понять мой вопрос легко: почему нет/screename/tips с методом DELETE? не будет правильнее? почему нужно добавить имя метода? – zanona

+0

относительно POST Я действительно вижу сейчас :), и я вижу, хочу ли я в этом случае добавлять советы для этих пользователей, мне нужно было бы сделать что-то вроде/screename/tips/users с POST, что в этом случае использование мелкой маршрутизации выглядите лучше как/tips/users с POST, поэтому я вижу, что каждый пост должен создать свое место назначения на маршруте сейчас, еще раз спасибо за разъяснение. Но один вопрос еще, вот что бы отражало метод User.first << Tips.first его не обновлять и не создавать его вставку на ассоциацию habtm, какова была бы правильная директива для него? – zanona

+0

Я вижу, к чему вы клоните. Мое лучшее предположение о том, почему DELETE для корня ресурса не является встроенным, заключается в том, что он будет произвольным с точки зрения стандартов, что следует удалить. Должны ли ВСЕ записи уничтожаться при вызове DELETE? Это было бы опасно. Итак, вам нужно добавить: collection => {: destroy_multiple =>: delete,: update_multiple =>: put}, чтобы получить то, что вы ищете. – bensie