Предоставление пользователям возможности либо выбрать из выпадающего меню, либо ввести свои собственные и добавить его в таблицу
Я прошу прощения за вопрос новичка. Но я пытался создать особый тип ассоциации, и все мои усилия терпели неудачу. Я хотел бы дать пользователям возможность выбирать свои родные города. Я отложил несколько вариантов, из которых они могут выбирать, но если его в данный момент нет в списке - я бы хотел, чтобы пользователь просто мог добавить его: "Не видеть свой город, добавьте его". Затем другой пользователь, который зарегистрируется позже, сможет увидеть новый город в своем списке. Я перечислил весь свой соответствующий код ниже, который работает до сих пор.
огромное спасибо
HomeCity Migration
class CreateHomecities < ActiveRecord::Migration[5.0]
def change
create_table :homecities do |t|
t.string :Hometown
t.timestamps
end
end
end
HomeCity Ссылка на пользователей
class AddHomecitiesRefToUsers < ActiveRecord::Migration[5.0]
def change
add_reference :users, :homecity, foreign_key: true
end
end
User.rb
class User < ApplicationRecord
cattr_accessor :current_user
belongs_to :homecity, optional: true
end
Homecity.rb
class Homecity < ApplicationRecord
has_many :users
end
edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :homecity %>
<br>
<%= f.collection_select :homecity_id, Homecity.all, :id, :Hometown %>
</div>
<div class="form-group">
<%= f.submit "Update", class: 'btn btn-lg btn-block btn-primary' %>
</div>
<% end %>
Seeds.rb
Homecity.destroy_all
bigapple = Homecity.create!(Hometown:"New York City")
techhub = Homecity.create!(Hometown:"San Francisco")
longhorns = Homecity.create!(Hometown:"Austin")
angels = Homecity.create!(Hometown:"Los Angeles")
windycity = Homecity.create!(Hometown:"Chicago")
Homecities_controller.rb (Создан новый файл контроллера на основе ответа)
class HomecitiesController < ApplicationController
before_action :authenticate_user!, only: [:new, :create]
def new
@homecity = Homecity.new
end
def create
@homecity = Homecity.new(homecity_params)
end
private
def homecity_params
params.require(:homecity).permit(:user_id)
end
end
2 ответа
Я понял это после нескольких часов поиска и подключения. Я перечислил то, что я сделал ниже, на случай, если кому-то еще понадобится помощь по аналогичному вопросу.
- Лучший способ решить эту проблему - использовать Selectize.js (Rubygems.org).
- Добавьте гем в ваш Gemfile - запустите пакетную установку
- Обязательно добавьте ( *= require selectize, *= require selectize.default) в ваш application.scss и добавьте (//= require selectize) в ваш application.js
- Вам нужно будет создать контроллер для Homecities, файл edit.js (настроить selectize, вашу базу данных и выпадающий список) и модал начальной загрузки в файле Edit.html.erb.
Homecities_controller.rb
class HomecitiesController < ApplicationController
before_action :authenticate_user!, only: [:new, :create]
def create
@homecity = Homecity.new(homecity_params)
if @homecity.save
render json: @homecity
else
render json: {errors: @homecity.errors.full_messages}
end
end
private
def homecity_params
params.require(:homecity).permit(:Hometown)
end
end
edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :homecity, "Home Town" %><br>
<%= f.select :homecity_id, Homecity.all.pluck(:Hometown, :id), {}, { class: "selectize" } %>
</div>
<div class="form-group">
<%= f.submit "Update", class: 'btn btn-lg btn-block btn-primary' %>
</div>
<% end %>
<div class="modal fade homecity-modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" >
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="mySmallModalLabel">Create a New City</h4>
</div>
<div class="modal-body">
<%= form_for Homecity.new do |f| %>
<div class="form-group">
<%= f.label :Hometown %>
<%= f.text_field :Hometown, class: "form-control" %>
</div>
<div class="form-group">
<%= f.submit class: "btn btn-primary" %>
</div>
<div class="modal-footer">
<span class="form-control-static pull-right">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</span>
</div>
<% end %>
</div>
</div>
</div>
</div>
edit.js
$(document).on("turbolinks:load", function() {
var selectizeCallback = null;
$(".homecity-modal").on("hide.bs.modal", function(e) {
if (selectizeCallback != null) {
selectizeCallback();
selecitzeCallback = null;
}
$("#new_homecity").trigger("reset");
$.rails.enableFormElements($("#new_homecity"));
});
$("#new_homecity").on("submit", function(e) {
e.preventDefault();
$.ajax({
method: "POST",
url: $(this).attr("action"),
data: $(this).serialize(),
success: function(response) {
selectizeCallback({value: response.id, text: response.Hometown});
selectizeCallback = null;
$(".homecity-modal").modal('toggle');
}
});
});
$(".selectize").selectize({
create: function(input, callback) {
selectizeCallback = callback;
$(".homecity-modal").modal();
$("#homecity_Hometown").val(input);
}
});
});
Вы заново изобретаете колесо - это нормально, если вы просто делаете это для целей обучения, я думаю, но если это реальное приложение, вам, скорее всего, лучше использовать сторонний драгоценный камень.
Исходные данные для этого могут быть легко обновлены (см. Readme)
https://github.com/loureirorg/city-state
Если вы не хотите использовать это, добавьте на страницу кнопку "Добавить город", которая затем сделает поле ввода доступным с помощью кнопки отправки, которая затем вставит новый город в вашу базу данных.