在使用带有Rails 5 API和RSpec的active_model_serializers时如何初始化参数

时间:2018-04-11 08:36:54

标签: rspec-rails active-model-serializers

我按照AMS guide设置了一个与Ember一起使用的Rails API应用程序。 我遇到的问题是如何创建一个参数传递给控制器​​动作? 我在RSpec请求规范中使用以下内容来初始化有效的params以传递到post操作:

context 'when shop does not have yet the selected language' do
      let(:new_language) { create(:language, tag: 'nl-BE') }
      let(:valid_params) { { language_id: new_language.id } }

      before { post "/shops/#{shop_id}/languages", params: valid_params.to_json, headers: headers }

      it 'returns status code 201' do
        expect(response).to have_http_status(201)
      end

      it 'has a new language added' do
        expect(json['data'].size).to eq(2)
      end
    end

在我在ShopLanguagesController强参数方法中所做的更改之前,它有效:

之前

def shop_language_params
  params.require(:shop_language).permit(:shop_id, :language_id, :modified_by)
end

def shop_language_params
  ActiveModelSerializers::Deserialization.jsonapi_parse!(params, only: [:shop, :language, :modified_by] )
end

似乎ActiveModelSerializers期望包含data键的不同params结构:

ActiveModelSerializers::Adapter::JsonApi::Deserialization::InvalidDocument:
       Invalid payload ({:data=>"Expected hash"}): {"language_id"=>2, "controller"=>"shop_languages", "action"=>"create", "shop_id"=>"1", "shop_language"=>{"language_id"=>2}}

我尝试通过添加valid_params密钥来修改data,如下所示:

let(:valid_params) { { data: { language: new_language, shop: user.shop } } }

现在我传入控制器的参数看起来像那样:

params: {"data":{"language":{"id":2,"tag":"nl-BE","created_at":"2018-04-11T08:29:46.299Z","updated_at":"2018-04-11T08:29:46.299Z"},"shop":{"id":1,"category":"Qui","fax":"(650) 065-5773","identifier":26168,"leader":"KELLEY LEHNER","modified_by":"Ms. Nelle Kuhlman","name":"CASSIN-WILL","opening_date":"2018-03-29","phone":"928.823.7550 x225","status":"tmp_closed","created_at":"2018-04-11T08:29:46.231Z","updated_at":"2018-04-11T08:29:46.231Z"}}}

但它也没有。

以下是来自Ember的控制器的参数:

ActiveModelSerializers::Deserialization.jsonapi_parse!解析之前:

controller params: <ActionController::Parameters {"data"=>{"attributes"=>{"modified-by"=>"Z28SCAMB"}, "relationships"=>{"shop"=>{"data"=>{"type"=>"shops", "id"=>"613"}}, "language"=>{"data"=>{"type"=>"languages", "id"=>"374"}}}, "type"=>"shop-languages"}, "controller"=>"shop_languages", "action"=>"create", "shop_id"=>"613"} permitted: false>

ActiveModelSerializers::Deserialization.jsonapi_parse!解析后:

{:shop_id=>"613", :language_id=>"374"}

1 个答案:

答案 0 :(得分:0)

我遇到的解决方案如下:

我在spec/support/request_spec_helper中定义了一个辅助方法:

def ams_json(model, attrs = {})
  resource = model.new(attrs)
  serialization = ActiveModelSerializers::SerializableResource.new(resource)
  serialization.to_json
end

我通过调用上面的帮助器方法修改了请求规范valid_params中的所有地方(ShopLanguage是应该初始化资源json的模型名称):

let(:new_language) { create(:language, tag: 'nl-BE') }

let(:valid_params) { ams_json(ShopLanguage, shop_id: shop_id, language_id: new_language.id) }

before { post "/shops/#{shop_id}/languages", params: valid_params, headers: headers }

它过去了。跳这有帮助。如果有更好的解决方案,欢迎随时欢迎!