为什么我的关联对象无法保存?

时间:2017-11-30 17:11:36

标签: ruby-on-rails ruby ruby-on-rails-4

(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后立即创建对象会更好吗?

任何帮助表示赞赏!谢谢!

2 个答案:

答案 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('&nbsp;&nbsp;&nbsp;').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