(Rails Newbie here)我有两种型号Usuario和Ficha。 Usuario与Ficha有一个联合。
以下是我的模特:
class Ficha < ApplicationRecord
belongs_to :user
belongs_to :usuario
end
class Usuario < ApplicationRecord
belongs_to :user
has_one :ficha, :dependent => :destroy
end
这是Usuario控制器:
class UsuariosController < ApplicationController
before_action :authenticate_user!
def index
@usuarios = Usuario.all
@usuario_last = Usuario.last(10)
@usuario_rev = @usuario_last.reverse
@user_count = current_user.usuarios
#Search
@usuario_search = if params[:term]
Usuario.where("name ~* ?", params[:term])
else
Usuario.all
end
@usuario_pag = @usuario_search.paginate(:page => params[:page], :per_page => 10)
end
def show
@usuario = Usuario.find(params[:id])
end
def new
@usuario = current_user.usuarios.build
end
def create
@usuario = current_user.usuarios.build(usuario_params)
@usuario.save
redirect_to @usuario
end
def edit
@usuario = Usuario.find(params[:id])
end
def update
@usuario = Usuario.find(params[:id])
if @usuario.update(usuario_params)
redirect_to @usuario
else
render 'edit'
end
end
def destroy
@usuario = Usuario.find(params[:id])
@usuario.destroy
redirect_to usuarios_path
end
private
def usuario_params
params.require(:usuario).permit(:name, :age, :doc, :docnum, :estadocivil, :country, :street,
:direction, :municipal, :zipcode, :tel1, :tel2)
end
end
这是我的Ficha控制器:
class FichasController < ApplicationController
before_action :authenticate_user!
def index
end
def show
@ficha = Ficha.find(params[:id])
end
def new
@usuario = Usuario.find(params[:usuario_id])
if @usuario.ficha.nil?
@ficha = @usuario.build_ficha
else
flash[:error] = "Ya tienes una ficha"
end
end
def create
@usuario = Usuario.find(params[:usuario_id])
@ficha = @usuario.build_ficha(ficha_params)
if @ficha.save
redirect_to @usuario, :notice => "Your ficha has been successfully created."
else
render :action => 'new'
end
end
def edit
#@ficha = Ficha.find(params[:id])
end
def update
@ficha = Ficha.find(params[:id])
if @ficha.update(ficha_params)
redirect_to @ficha
else
render 'edit'
end
end
def destroy
@usuario = Usuario.find(params[:usuario])
@ficha = @usuario.fichas.find(params[:id])
@ficha.destroy
redirect_to fichas_path
end
private
def ficha_params
params.require(:ficha).permit(:name, :age, :doc, :docnum, :estadocivil, :country, :street,
:direction, :municipal, :zipcode, :tel1, :tel2, :time, :redes, :estudios, :profession,
:laboral, :discapacity, :percent, :derivado1, :derivado2, :derivacion, :nombredelprofesional,
:observaciones, :conocio, :signature, :date, :term)
end
end
我在控制器中创建ficha的某个地方出错了吗?在usuario模型中使用after_create后立即创建对象会更好吗?
任何帮助表示赞赏!谢谢!
答案 0 :(得分:1)
是的,你以正确的方式解决这个问题。如果您的<script type='text/javascript'>
var zoneMap;
var currentRestMarkers = [];
var markerInfoWindow;
var distances = [{"fee":2,"distance":5,"available":1},{"fee":3,"distance":7,"available":1},{"available":1,"distance":9,"fee":7},{"fee":9,"available":0,"distance":10}];
var ajaxResponse = {"success":[{"duration":"11.5","name":"Backyard Bistro","lng":-78.7253,"lat":35.7989,"distance":6.64,"restId":"179"},{"lat":35.7796,"lng":-78.6758,"restId":"180","distance":7.5,"name":"Baja Burrito","duration":"13.3"},{"name":"Mi Rancho","duration":"15.6","lng":-78.6482,"lat":35.7491,"restId":"183","distance":6.32},{"lat":35.7757,"lng":-78.6363,"distance":4.67,"restId":"188","name":"El Rodeo Downtown","duration":"13.7"},{"duration":"9.2","name":"El Rodeo North","lng":-78.6262,"lat":35.8137,"distance":3.35,"restId":"189"},{"name":"Fallon's Flowers","duration":"9.1","restId":"192","distance":2.92,"lat":35.789,"lng":-78.6507},{"lng":-78.6397,"lat":35.7742,"restId":"193","distance":4.62,"name":"Fire Wok","duration":"14.1"},{"lng":-78.6131,"lat":35.8051,"restId":"194","distance":6.21,"name":"Gateway","duration":"9.8"},{"restId":"195","distance":27.99,"lng":-79.0564,"lat":35.9152,"name":"Gift Cards ","duration":"35.6"},{"name":"Jumbo China","duration":"8.5","lng":-78.6262,"lat":35.819,"distance":2.87,"restId":"197"},{"lng":-78.6456,"lat":35.8817,"restId":"198","distance":4.93,"name":"La Rancherita","duration":"12.0"},{"duration":"8.9","name":"Mami Nora's","restId":"205","distance":3.35,"lat":35.8137,"lng":-78.6271},{"distance":2.94,"restId":"209","lat":35.7883,"lng":-78.6474,"duration":"8.0","name":"Mellow Mushroom"},{"distance":7.88,"restId":"212","lng":-78.7387,"lat":35.7878,"duration":"12.3","name":"Ole Time BBQ"},{"lng":-78.6388,"lat":35.8374,"restId":"214","distance":2.23,"duration":"7.0","name":"Piola"},{"name":"The Remedy Diner 2.0 - Brunch","duration":"11.9","lng":-78.656,"lat":35.7824,"distance":4.24,"restId":"216"},{"lng":-78.656,"lat":35.7824,"restId":"217","distance":4.24,"duration":"11.9","name":"The Remedy Diner 2.0"},{"distance":7.66,"restId":"218","lng":-78.6773,"lat":35.7777,"name":"Sammy's Tap & Grill","duration":"13.4"},{"lng":-78.621,"lat":35.8238,"distance":4.39,"restId":"219","duration":"8.4","name":"Shaba Shabu"},{"name":"Spring Rolls","duration":"5.9","distance":1.88,"restId":"220","lng":-78.6409,"lat":35.8399},{"duration":"9.6","name":"Thaiphoon","restId":"222","distance":3.2,"lat":35.7845,"lng":-78.6477},{"lat":35.7776,"lng":-78.6398,"restId":"223","distance":4.3,"duration":"11.6","name":"The Big Easy"},{"lng":-78.6433,"lat":35.8364,"restId":"225","distance":1.68,"duration":"5.5","name":"The Q Shack"},{"duration":"14.4","name":"Vic's Italian","lng":-78.6356,"lat":35.7759,"restId":"226","distance":4.72},{"restId":"227","distance":1.68,"lng":-78.6433,"lat":35.8364,"name":"Which Wich North Hills","duration":"5.5"},{"lat":35.7912,"lng":-78.6799,"restId":"245","distance":5.89,"duration":"10.5","name":"The Wild Cook's Indian Grill"},{"lng":-78.6237,"lat":35.873,"restId":"301","distance":4.68,"name":"Taj Mahal North","duration":"12.9"},{"restId":"820","distance":6.29,"lng":-78.6825,"lat":35.8986,"duration":"14.5","name":"El Dorado "},{"name":"Taza Grill","duration":"12.8","restId":"821","distance":4.84,"lat":35.8693,"lng":-78.6211},{"duration":"14.9","name":"Sassool","restId":"824","distance":6.83,"lat":35.9043,"lng":-78.6567},{"lng":-78.5797,"lat":35.8477,"distance":8.45,"restId":"830","name":"Alpaca Peruvian Charcoal Chicken","duration":"13.9"},{"distance":6.21,"restId":"831","lat":35.899,"lng":-78.653,"name":"Shish Kabob Six Forks","duration":"14.1"},{"distance":2.87,"restId":"923","lng":-78.6262,"lat":35.819,"name":"Tropical Picken Chicken","duration":"8.5"},{"duration":"10.3","name":"Wicked Taco","lat":35.7852,"lng":-78.6923,"restId":"931","distance":6.48},{"duration":"14.8","name":"Despina's Cafe","restId":"1142","distance":6.31,"lng":-78.6824,"lat":35.9015},{"duration":"4.7","name":"WhichWich Crabtree","lat":35.8391,"lng":-78.6752,"distance":1.7,"restId":"1242"},{"duration":"6.3","name":"Pharaoh's Grill at North Hills","distance":1.86,"restId":"1296","lng":-78.6434,"lat":35.8403},{"name":"Pharaoh's at the Museum","duration":"12.2","restId":"1297","distance":4.43,"lat":35.7818,"lng":-78.6386},{"restId":"1298","distance":2.54,"lng":-78.6298,"lat":35.8215,"name":"Gorilla Grill","duration":"6.5"},{"name":"My Way Tavern","duration":"9.8","lng":-78.6506,"lat":35.7872,"restId":"1307","distance":3.04}]};
function initialize() {
var myLatlng = new google.maps.LatLng(35.8013,-78.6409);
var geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: 13,
center: myLatlng,
panControl: false,
zoomControl: true,
mapTypeControl: false,
scaleControl: true,
streetViewControl: false,
overviewMapControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
zoneMap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var addressMarker = new google.maps.Marker({
position: zoneMap.center,
map: zoneMap,
clickable: true,
draggable: true,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
});
google.maps.event.addListener(addressMarker, 'dragend', function(event) {
var markerNewLatLng=event.latLng;
geocoder.geocode({'latLng': markerNewLatLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
showAvailableRests(markerNewLatLng.lat(),markerNewLatLng.lng());
}
else {
console.log('Geocoder failed due to: ' + status);
}
});
});
}
function loadScript() {
var acScript = document.createElement('script');
acScript.type = 'text/javascript';
acScript.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize';
document.body.appendChild(acScript);
}
function showAvailableRests(whichLat,whichLng) {
var rest_list = jQuery('#rest_list');
jQuery(rest_list).empty();
jQuery('#restCount').html('');
if (currentRestMarkers.length > 0) {
for (var i in currentRestMarkers) {
currentRestMarkers[i].setMap(null);
}
currentRestMarkers = [];
}
var restCount = 0;
for (var i=0; i < ajaxResponse.success.length; i++ ) {
var iconColor = 'green.png';
var available = 1;
var tierClass = 'tier1';
for (var j=0; j < distances.length; j++ ) {
if (ajaxResponse.success[i].distance >= distances[j].distance) {
if (distances[j].available == 0) {
available = 0;
}
if (j === 0) {
iconColor = 'yellow.png';
tierClass = 'tier2';
}
else if (j === 1) {
iconColor = 'orange.png';
tierClass = 'tier3';
}
else if (j > 1) {
iconColor = 'purple.png';
tierClass = 'tier4';
}
}
else {
break; // if it is not greater than the shorter distance, it is not greater than longer ones either
}
}
if (available === 0) { // if this restaurant is not available at this distance
//continue; // skip the rest for unavailable
iconColor = 'red.png';
tierClass = 'unavailable';
}
else {
restCount++;
}
var restDiv = jQuery(document.createElement('div'));
var distanceTier = jQuery(document.createElement('span')).html(' ').addClass('distance-tier ' + tierClass).appendTo(restDiv);
var restDist = jQuery(document.createElement('span')).html(ajaxResponse.success[i].distance + ' mi.').addClass('rest-distance').appendTo(restDiv);
var restName = jQuery(document.createElement('span')).html(ajaxResponse.success[i].name).addClass('rest-name').appendTo(restDiv);
jQuery(restDiv).appendTo(rest_list);
var restMarkerPosition = new google.maps.LatLng(ajaxResponse.success[i].lat,ajaxResponse.success[i].lng);
var restMarker = new google.maps.Marker({
position: restMarkerPosition,
map: zoneMap,
clickable: false,
draggable: false,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/' + iconColor
});
currentRestMarkers.push(restMarker);
google.maps.event.addListener(restMarker, 'mouseover', function(e) {
console.log('mouseover event fired'); // the mouseover event is never fired!!!
showRestWindow(e, ajaxResponse.success[i].name, ajaxResponse.success[i].distance);
});
/*restMarker.addListener('mouseover', function() {
new google.maps.InfoWindow({
content: "<div><strong>" + ajaxResponse.success[i].name + "<\/strong><br>" + ajaxResponse.success[i].distance + " miles<\/div>",
disableAutoPan: true,
});
markerInfoWindow.open(zoneMap, this);
});*/
jQuery('#restCount').html(restCount);
}
}
function showRestWindow(event, name, distance) {
markerInfoWindow = new google.maps.InfoWindow({
content: "<div><strong>" + name + "<\/strong><br>" + distance + " miles<\/div>",
disableAutoPan: true,
position: event.latLng,
});
markerInfoWindow.open(zoneMap);
};
jQuery(document).ready(function () {
loadScript();
return false;
});
</script>
<div id='map_container'>
<div id='map_canvas'></div>
</div>
<div id='column_right'>
<p><b>Available Restaurants: <span id='restCount'></span></b></p>
<div id='rest_list'></div>
</div>
对象无法保存,则可能是因为验证错误或未正确关联。
查看debugging with the console命令,了解如何解决这些类型的问题,方法是在保存尝试后插入@ficha
以查看console
对象是否附加了任何错误
Web控制台有点像byebug,但它在浏览器中运行。在任何 您正在开发的页面,您可以在a的上下文中请求控制台 视图或控制器。控制台将呈现在HTML旁边 内容。 4.1控制台
在任何控制器操作或视图中,您可以通过调用控制台 调用控制台方法。
答案 1 :(得分:1)
在Rails 4.2.1中
我在这里看不到你使用了#accepted; accepts_nested_attributes_for&#39;。阅读http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
试试这些
class Ficha < ApplicationRecord
belongs_to :user
belongs_to :usuario
end
class Usuario < ApplicationRecord
belongs_to :user
has_one :ficha, :dependent => :destroy
accepts_nested_attributes_for :ficha
end
你也可以在UsuariosController中使用ficha_attributs,就像这些
一样private
def usuario_params
params.require(:usuario).permit(:name, :age, :doc, :docnum, :estadocivil, :country, :street,:direction, :municipal, :zipcode, :tel1, :tel2, ficha_attributes: [# Write ficha attributes you want save])
end