Активная запись find_by возвращает ноль - PullRequest
0 голосов
/ 01 апреля 2020

Кажется, я не могу заставить find_by работать, когда вы запрашиваете результаты, такие как

GET /users.json?first_name=Tyrone&last_name=Slothrop "

должны возвращать пользователей с именем first_name Тайрон и его фамилия - Слотроп.

Возвращает ноль, потому что все параметры в этом запросе равны нулю, кроме first_name и last_name. Я застрял, чтобы заставить его принять только параметры запроса и выполнить поиск по ним. Любой совет ?

  class Api::V1::UsersController < ApplicationController

  def index
    @users = User.find_by(id: params[:id], first_name: params[:first_name], 
                            last_name: params[:last_name], email: params[:email],
                            city: params[:city], state: params[:state])
    respond_to do |format|
      format.json { render json: @users.to_json, status: :ok }
    end
  end
end

вот ссылка на полный репозиторий mt https://github.com/jslack2537/apiDemoApp

вывод журнала dev для запроса

Started GET "/api/v1/users.json?first_name=Tyrone&last_name=Slothrop" for 10.0.2.2 at 2020-04-01 02:42:17 +0000
Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Api::V1::UsersController#index as JSON
  Parameters: {"first_name"=>"Tyrone", "last_name"=>"Slothrop"}
  [1m[36mUser Load (4.4ms)[0m  [1m[34mSELECT  "users".* FROM "users" WHERE "users"."id" IS NULL AND "users"."first_name" = ? AND "users"."last_name" = ? AND "users"."email" IS NULL AND "users"."city" IS NULL AND "users"."state" IS NULL LIMIT ?[0m  [["first_name", "Tyrone"], ["last_name", "Slothrop"], ["LIMIT", 1]]
  ↳ app/controllers/api/v1/users_controller.rb:5
Completed 200 OK in 7ms (Views: 0.1ms | ActiveRecord: 4.4ms)

EDIT ** * Теперь я получаю эту ошибку с моим обновленным кодом NoMethodError (неопределенный метод `split 'для nil: NilClass):

class Api::V1::UsersController < ApplicationController

  def index
    ids = params[:id].split(",")
    if params[:id].present?
  @users = User.where(user_params.merge!(id: ids)).paginate(:per_page => params[:size], :page => params[:page]).order('id DESC')
   respond_to do |format|
    format.json { render json: @users.to_json, status: :ok }
    end
   else
    @users = User.where(user_params).paginate(:per_page => params[:size], :page => params[:page]).order('id DESC')
    respond_to do |format|
     format.json { render json: @users.to_json, status: :ok }
     end
    end
  end

  private

  def user_params
   params.permit(:first_name, :last_name, :email, :city, :state)
  end
end

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Я полагаю, что вы должны разрешить параметры, я загрузил ваше хранилище и смог получить нужный запрос, разрешив параметры, например:

class Api::V1::UsersController < ApplicationController

 def index
  @users = User.find_by(user_params)
  respond_to do |format|
   format.json { render json: @users.to_json, status: :ok }
  end
 end

 private

 def user_params
  params.permit(:first_name, :last_name, :email, :city, :state)
 end
end

Теперь, если вы попробуете этот запрос http://localhost:3000/api/v1/users?first_name=Tyrone&last_name=Slothrop&city=Chicago в журналах вы должны увидеть, что единственные переданные вами параметры используются для поиска:

  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."first_name" = ? AND "users"."last_name" = ? AND "users"."email" = ? AND "users"."city" = ? LIMIT ?  [["first_name", "Tyrone"], ["last_name", "Slothrop"], ["email", "jean@email.com"], ["city", "Chicago"], ["LIMIT", 1]]

↳ app / controllers / api / v1 / users_controller.rb: 11

Rails просто разрешает параметры, определенные в user_params, поэтому, если они отсутствуют, они будут просто проигнорированы

Редактировать: вернуть список совпадений, которые вы должны использовать, где:

  def index
   @users = User.where(user_params)
   respond_to do |format|
    format.json { render json: @users.to_json, status: :ok }
   end
  end

Чтобы разрешить несколько параметров, например, разрешить несколько полей first_name, вы можете сделать:

  def user_params
   params.permit(:last_name, :email, :city, :state, first_name: [])
  end

Не забудьте поместить элементы массива в конец разрешения, чтобы избежать синтаксических ошибок, и после этого вы можете запросите имя наподобие этого: http://localhost:3000/api/v1/users?first_name[]=John&first_name[]=Jean,

Этот URL может быть довольно утомительным для создания, поэтому я хотел бы предложить, что если вы создаете API, вы всегда можете отправлять параметры в теле требуемого То есть, вот так:

{
 "first_name": ["John", "Jean"]
}

И это будет иметь точное поведение для передачи параметров в URL.

Если вы строго хотите отправить идентификатор как id = 1,2, 3, что вы можете сделать что-то вроде:

class Api::V1::UsersController < ApplicationController

 def index
  ids = params[:id].split(",")
  @users = User.where(user_params.merge!(id: ids))
  respond_to do |format|
   format.json { render json: @users.to_json, status: :ok }
  end
 end

 private

 def user_params
  params.permit(:last_name, :email, :city, :state, :first_name)
 end
end

user_params.merge! сделает свое дело, так как он перезапишет или добавит ключ id к вашим user_params ha sh.

0 голосов
/ 01 апреля 2020

Я вижу ошибку в том, как вы отправляете запрос в API

try: /users.json?first_name=Tyrone&last_name=Slothrop"
вместо: / users.jsonfirst_name = Tyrone & last_name = Slothrop "

вы видите недостающее"? " в начале строки запроса?


Изменить после исправления URL-адрес запроса:

, возможно, лучший подход для вашего запроса - использовать вместо вместо find_by.
пример:

user = User.where(id: params[:id])
.where(first_name: params[:first_name])
.where(last_name: params[:last_name])
.where(email: params[:email])
.where(city: params[:city])
.where(state: params[:state])
.first
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...