【问题标题】:rails polymorphic Association doesn't save idrails多态关联不保存id
【发布时间】:2014-06-01 22:22:40
【问题描述】:

这很奇怪,我不明白。

我得到了一个多态的新形式来存储地址,create 方法实际上并没有创建关联。

位置/新

%= form_for [@mappable, @location] do |form| %>
<div class="inline-label-container">
  <%= form.label :street_address, "street address", :class => "inline" %>
  <%= form.text_field :street_address, :onkeyup => 'timed_input(this)', :value => current_user.location.address, :autocomplete => :off %>
  <%= form.label :location_description, "Found Location"%>
  <%= form.text_field :address, :value => @user.location.address, :disabled => :true%>
  <%= form.hidden_field :google_address, :value => @user.location.address %>
  <%= form.hidden_field :latitude, :value => @user.location.latitude %>
  <%= form.hidden_field :longitude, :value => @user.location.longitude %>
  <%= form.submit "Enter Location", :class => "btn btn-large btn-success" %>
  you can also drag and drop marker!
  <small>
  </small>
</div>
<%end%>

location_controller.rb

def new
    @user = current_user
    @mappable = load_mappable
    @location = @mappable.build_location
end


 def create

        @user = current_user
    @mappable = load_mappable
    @location = @mappable.build_location(params[:location], :mappable_id => @mappable.id, :mappable_type => @mappable.class.base_class.name)

    respond_to do |format|
    if @location.save     
      format.html { redirect_to :back, notice: "#{@mappable.id}, #{@mappable.class.base_class.name}"}
      format.json { render :json => :back, :status => :created, :location => @user }
      #redirect_to @commentable, notice: "Comment created."
    else
      format.html { redirect_to root_path }
      format.json { render :json => @location.errors, :status => :unprocessable_entity }
      #render :new
    end
    end

  def load_mappable
resource, id = request.path.split('/')[1,2]
@mappable = resource.singularize.classify.constantize.find(id)

结束

在 create 方法中传递 mappable_id 和 type 是我最后一次尝试获取它们。这真的很奇怪,因为在创建后通知中会显示正确的 mappable_id 和 mappable_type

2.1.1 :085 > Location.last
  Location Load (0.6ms)  SELECT "locations".* FROM "locations" ORDER BY "locations"."id" DESC LIMIT 1
 => #<Location id: 95, address: nil, longitude: -74.009457, latitude: 40.704513, postcode: nil, created_at: "2014-06-01 19:06:19", 
updated_at: "2014-06-01 19:06:20", actor_id: nil, country: nil, country_code: nil, postal_code: nil, city: nil, political: nil, loc
ality: nil, sublocality: nil, street_address: "108 Pearl Street", google_address: "108 Pearl Street, New York, NY 10004, USA", ward
_id: nil, **mappable_id: nil**, mappable_type: "Skill"> 

为什么缺少 mappable_id ?请帮忙

Location.rb

class Location < ActiveRecord::Base
  include ActiveModel::Validations

  belongs_to :mappable, :polymorphic => true

  searchkick

  has_one :map, :dependent => :destroy
  has_one :group, :through => :map, :source => :mappable, :source_type => 'Group'

  belongs_to :ward
  accepts_nested_attributes_for :ward
  has_one :localfeed
  attr_accessible :address, :latitude, :longitude, :postcode, :user_id, :actor_id, :group_id,
    :country,  
    :country_code,  
    :postal_code,  
    :city,  
    :political,  
    :locality,  
    :sublocality,  
    :street_address,
    :google_address,
    :location_attributes,
    :mappable_id,
    :mappable_type,
    :ward_id

  geocoded_by :to_s
  #before_save :geolocate
  validate :street_address, :address_validator => true

  after_validation :geocode
  #before_save :geolocate
  after_save :createward
  #after_save :ward_present #creates new ward and feed if not existant

  def address_changed?
  attrs = %w(street_address city postal_code)
  attrs.any?{|a| send "#{a}_changed?"}
  end

  def to_s
    "#{google_address} #{city} #{postal_code}" +" GB"
  end

  def gmaps4rails_address
    address
  end

  def ward_present
    if self.ward_id = nil?
      w = Ward.find_by_name(self.city)
      self.ward_id = w.id
    else
      self.destroy
    end
  end

    geocoded_by :to_s do |prof,results|
  if result = results.select{|res| res.country_code == "GB" }.first
    unless (result.latitude.nil? || result.longitude.nil?)
      prof.latitude = result.latitude
      prof.longitude = result.longitude
      prof.country = result.country
      prof.postal_code = result.postal_code
      prof.city = result.city
      #prof.political = result.political
     # prof.locality = result.locality
    #  prof.sublocality = result.sublocality
      prof.street_address = result.street_address
    end
    result.coordinates
  end
end

  def geolocate 
    res = GoogleGeocoder.geocode(to_s)

    if res.success

    self.latitude = res.latitude
    self.lonitude = res.longitude
    else
      errors[:base] << "geocoding failed, check address"
      return false
  end
  end

  def createward
    unless self.city.nil?
    w = Ward.find_by_name(self.city)
    if w.nil?
    c = self.create_ward!({:name => self.city, :city => self.city}) # should be [name => self.sublocality]
    self.ward_id = c.id
    else
    self.ward_id = w.id
    end
    end
  end


  def self.groups
     self.where(:user_id => nil)
  end
  def self.users
    self.where(:group_id => nil)
  end
  def self.users_city(city)
    self.where(:mappable_type => "User", :city => city).map(&:mappable_id).uniq
    #returns array  of user_ids!
  end

  def search_and_fill_latlng(address=nil)
    okresponse = false
    geocoder = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="

    if address == nil
      address = self.address
    end

    if address != nil && address != ""
      url = URI.escape(geocoder+address)
      resp = RestClient.get(url)
      result = JSON.parse(resp.body)

      if result["status"] == "OK"
        self.latitude = result["results"][0]["geometry"]["location"]["lat"]
        self.longitude = result["results"][0]["geometry"]["location"]["lng"]
        okresponse = true
      end
    end
    okresponse
  end


end

技能.rb

class Skill < ActiveRecord::Base

  attr_accessible :avatar_attributes, :photo_attributes, :name, :description,:skill_type_id, :properties, :teachers_title, :necessary_resources, :level, :required_experience,
  :price, :start_date, :min_students, :max_students, :activity_duration, :location_id, :user_id, :location_attributes, :skill_type_attributes


  belongs_to :user
  belongs_to :skill_type
  has_one :ward, :as => :warded
  accepts_nested_attributes_for :skill_type

  has_one :location, :as => :mappable
  accepts_nested_attributes_for :location

包括位置和技能这两个模型类。

控制台

Started POST "/skills/10/locations" for 127.0.0.1 at 2014-06-02 13:11:32 +0100
Processing by LocationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"hgJxwarAwYS4RP3GidzBnd3MRShCnvDltb0r6ULblBo=", "location"=>{"street_address"=>"1
01 Pearl Street cardiff", "google_address"=>"101 Pearl Street, Cardiff CF24 1NE, UK", "latitude"=>"51.4866055", "longitude"=>"-3.15
24131999999554"}, "commit"=>"Enter Location", "skill_id"=>"10"}
  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 6 LIMIT 1
  Location Load (0.6ms)  SELECT "locations".* FROM "locations" WHERE "locations"."mappable_id" = 6 AND "locations"."mappable_type" 
= 'User' LIMIT 1
  Avatar Load (0.5ms)  SELECT "avatars".* FROM "avatars" WHERE "avatars"."avatarable_id" = 6 AND "avatars"."avatarable_type" = 'Use
r' LIMIT 1
  Profile Load (0.5ms)  SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = 6 LIMIT 1
  Skill Load (0.4ms)  SELECT "skills".* FROM "skills" WHERE "skills"."id" = $1 LIMIT 1  [["id", "10"]]
  CACHE (0.0ms)  SELECT "skills".* FROM "skills" WHERE "skills"."id" = $1 LIMIT 1  [["id", "10"]]
  Location Load (0.6ms)  SELECT "locations".* FROM "locations" WHERE "locations"."mappable_id" = 10 AND "locations"."mappable_type"
 = 'Skill' LIMIT 1
   (0.1ms)  BEGIN
  SQL (0.8ms)  INSERT INTO "locations" ("actor_id", "address", "city", "country", "country_code", "created_at", "google_address", "
latitude", "locality", "longitude", "mappable_id", "mappable_type", "political", "postal_code", "postcode", "street_address", "subl
ocality", "updated_at", "ward_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19) RE
TURNING "id"  [["actor_id", nil], ["address", nil], ["city", "Cardiff"], ["country", "United Kingdom"], ["country_code", nil], ["cr
eated_at", Mon, 02 Jun 2014 12:11:33 UTC +00:00], ["google_address", "101 Pearl Street, Cardiff CF24 1NE, UK"], ["latitude", 51.486
6055], ["locality", nil], ["longitude", -3.1524132], ["mappable_id", 10], ["mappable_type", "Skill"], ["political", nil], ["postal_
code", "CF24 1NE"], ["postcode", nil], ["street_address", "101 Pearl Street"], ["sublocality", nil], ["updated_at", Mon, 02 Jun 201
4 12:11:33 UTC +00:00], ["ward_id", nil]]
  Ward Load (0.5ms)  SELECT "wards".* FROM "wards" WHERE "wards"."name" = 'Cardiff' LIMIT 1
   (0.8ms)  COMMIT

【问题讨论】:

  • 您使用的是哪些导轨?如果它的rails 4,你能确定你已经允许mappable_id吗?
  • rails 3.2,所有变量都在 attar_accessible 列表中
  • 因为[@mappable, @location],我假设这是一个嵌套路由,在这种情况下,您应该使用params[:something_id] 来搜索@mappable 而不仅仅是params[:id]。更奇怪的是,当您执行 find(params[:id]) 时不会出现异常,因为当找不到记录时应该会引发异常。
  • 是的,正如@jvnill 指出的那样。它们是嵌套的吗?您可以在提交表单时从控制台或日志中发布您的参数吗?
  • 你能告诉我们你的models吗?您不必显式设置 mappable_idmappable_type

标签: ruby-on-rails ruby-on-rails-3 associations polymorphic-associations


【解决方案1】:

不完全知道为什么,但问题在于 Location_controller 新方法 将 @Location = @mappable.build_location 更改为 @location = Location.new 并开始工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多