Как передать данные из представления, пришедшие из внешнего API, в контроллер? - PullRequest
0 голосов
/ 14 октября 2018

Итак, я хочу передать данные из представления, которое было отображено из внешнего API, в контроллер, чтобы иметь возможность сохранить идентификатор в таблице модели / базы данных.

Это мое представление:

<h1>Heroes</h1>
<% @response.each do |hero| %>
  <div class = "hero_wrap">
    <div class = "img">
      <img src="https://api.opendota.com<%= hero["img"]%>", id ="hero_img"/>
    </div>
    <div class = "fave_container">
    <%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>
    <%= hero["id"]%>
  </div>
    <div class = "hero_name">
      <%= hero["localized_name"] %>
    </div>
  </div>
<% end %>

Мой контроллер:

# heroes_controller

class HeroesController < ApplicationController
  def index
    @response = HTTParty.get("https://api.opendota.com/api/heroStats")
  end

  def create
    @hero= Hero.new(params[:id])

    @hero.save
    redirect_to @hero
  end
end

Маршруты:

Rails.application.routes.draw do

  get '/signup', to: 'users#new' 
  get  'pages/home'

  resources :pro_players
  devise_for :users
  resources :heroes
  resources :users

  root 'pages#home'
end

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

это мое веб-приложение

журнал сервера при нажатии на значок звезды со ссылкой:

Started GET "/heros?custom_hero_id=1&method=post" for 127.0.0.1 at 
2018-10-15 09:20:53 +0800
Processing by HerosController#index as HTML
  Parameters: {"custom_hero_id"=>"1", "method"=>"post"}
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord- 
5.2.1/lib/active_record/log_subscriber.rb:98
  Rendering heros/index.html.erb within layouts/application
  Rendered heros/index.html.erb within layouts/application (42.2ms)
  Rendered layouts/_header.html.erb (1.1ms)
  Rendered layouts/_footer.html.erb (0.4ms)
    Completed 200 OK in 770ms (Views: 83.3ms | ActiveRecord: 0.7ms)

Обновленный журнал:

Started POST "/heros?custom_hero_id=21" for 127.0.0.1 at 2018-10-15 10:13:17 +0800
Processing by HerosController#create as HTML
  Parameters: {"authenticity_token"=>"PHDEXdDmPhPX+VdloU2y6yONY5HN5wI2lIfOaSbSKj9+RvTO5Ua3QPuTcreLZtGNDFPaSOXhDVyve6J69+1CQQ==", "custom_hero_id"=>"21"}
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
      ↳/home/don/.asdf/installs/ruby/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
   (0.2ms)  BEGIN
  ↳ app/controllers/heros_controller.rb:9
      Hero Create (0.4ms)  INSERT INTO "heros" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2018-10-15 02:13:17.032248"], ["updated_at", "2018-10-15 02:13:17.032248"]]
      ↳ app/controllers/heros_controller.rb:9
   (42.3ms)  COMMIT
      ↳ app/controllers/heros_controller.rb:9
 Redirected to http://localhost:3000/heros/10
Completed 302 Found in 59ms (ActiveRecord: 46.9ms)


Started GET "/heros/10" for 127.0.0.1 at 2018-10-15 10:13:17 +0800

AbstractController::ActionNotFound (The action 'show' could not be found for HerosController):

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Атрибут :id по умолчанию является автоинкрементом атрибута типа данных integer, который устанавливает его значение под капотом при каждом новом экземпляре модели.создан .Есть несколько способов переопределить его поведение или установить его значение явно, но, учитывая, что вы довольно плохо знакомы с технологией , я не рекомендую для вас.Вместо этого я рекомендую более простое решение использования другого атрибута для хранения hero["id"]

Шаги:

1) Создайте миграцию для создания новогостолбец (скажем, custom_hero_id) в таблице heroes

rails g migration add_custom_hero_id_to_heroes custom_hero_id:integer

и rake db:migrate

2) Измените

<%= link_to(image_tag('fave.png', class: "fave_img"), new_hero_path) %>

на

<%= link_to(image_tag('fave.png', class: "fave_img"), heroes_path(custom_hero_id: hero["id"]), method: :post) %>

3) Наконец измените ваше действие create на ниже

def create
  @hero= Hero.create(custom_hero_id: params[:custom_hero_id])
  redirect_to @hero
end

Обновление:

По неизвестной причине custom_hero_id несохранение в БД.Вероятно, из-за запрещенные атрибуты ошибка.Попробуйте изменить его на

def create
  @hero = Hero.new(hero_params)

  if @hero.save
    redirect_to @hero
  end
end

private
def hero_params
  params.permit(:custom_hero_id)
end
0 голосов
/ 14 октября 2018

Вы хотите сохранить идентификатор героя или его имя?

Я бы посоветовал создать метод в вашей модели героя.Что-то вроде

// heroe.rb

def save_api_heroes_to_db(response)
  response.each do |hero|
    unless hero[:localized_name].exists?
      hero.create(id: hero[:id], name: hero[:localized_name], image: hero[:img])
    end
  end
end

Этот метод сохранит идентификатор, имя и изображение героя в вашей базе данных (если он еще не существует).

Вы просто должны вызвать его в своем методе indexв контроллере вашего героя.

Надеюсь, это поможет.

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