本文介绍了在PostsController中的NoMethodError#创建未定义的方法`latitude ='“保存lat和long到连接的表”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将这些坐标从图像的元数据我上传与回形针到另一个表称为地方。所以坐标转到地方表。地方资讯表中有列经纬度。提交后,我遇到这个错误。错误的突出部分是self.latitude = parse_latlong(etc ....)。

I am trying to post these coordinates from the metadata of the image i upload with paperclip to another table called places."so coordinates go to places table." There are columns latitude and longitude in the places table. After submitting the post i run into this error. The highlighted portion of the error is self.latitude=parse_latlong(etc....).

post_id是places表中的外键。这个工作以前当我在post表中有纬度和经度。但现在我给了它自己的表更好的数据库结构..我只是需要知道如何让我的帖子控制器与我的位置控制器,如果这是主要的问题工作

post_id is a foreign key in the places table. This worked previously when i had latitude and longitude in the post table. but now i gave it its own table for better database structure.. i just need to know how to get my post controller to work with my places controller if that is the main problem??

地方控制器

class PlacesController < ApplicationController
    before_action :set_post

def create  
  @place = @post.places.build(place_params)


  if @place.save
    flash[:success] = "coorinates saved"
    redirect_to :back
  else
    flash[:alert] = "Check the form, something went wrong."
    render root_path
  end
end


private

def place_params  
  params.require(:place).permit(:continent, :country, :city, :address, :latitude, :longitude)
end

def set_post  
  @post = Post.find(params[:post_id])
end  
end

post控制器

class PostsController < ApplicationController

before_action :authenticate_user!, :except => [:show, :index, :new]

before_action :set_post, only: [:show, :edit, :update, :destroy]

before_action :owned_post, only: [:edit, :update, :destroy]  

  def index
    @post = Post.new
    @posts = Post.all
  end

  def show

    @post = Post.find(params[:id])
  end

  def new
    @post = current_user.posts.build

    @posts = Post.all
  end

  def create
     @post = current_user.posts.build(post_params)

     if @post.save
      flash[:success] = "Your post has been created!"
      redirect_to root_path
    else
      flash[:alert] = "Your new post couldn't be created!  Please check the form."
      render :new
    end
  end

  def edit
    @post = Post.find(params[:id])
  end

  def update
     if @post.update(post_params)
      flash[:success] = "Post updated."
      redirect_to root_path
    else
      flash.now[:alert] = "Update failed.  Please check the form."
      render :edit
    end
  end

  def destroy
    @post.destroy
    flash[:success] = "Your Post has been removed."
    redirect_to root_path
  end

  private

  def post_params
    params.require(:post).permit(:image, :caption, :address)
  end

  def set_post
    @post = Post.find(params[:id])
  end

  def owned_post  
  unless current_user == @post.user
    flash[:alert] = "That post doesn't belong to you!"
    redirect_to root_path
  end
end  

end


$ b b

post模型

post model

class Post < ActiveRecord::Base

belongs_to :user
belongs_to :place

has_many :comments, dependent: :destroy
has_one :place, dependent: :destroy

    validates :user_id, presence: true
    validates :image, presence: true


accepts_nested_attributes_for :place

  has_attached_file :image, styles: { :medium => "640x" }

  validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/

after_post_process :save_latlong


private

  def save_latlong
  exif_data = MiniExiftool.new(image.queued_for_write[:original].path)
  self.latitude = parse_latlong(exif_data['gpslatitude'])
  self.longitude = parse_latlong(exif_data['gpslongitude'])
end

def parse_latlong(latlong)
  return unless latlong
  match, degrees, minutes, seconds, rotation = /(\d+) deg (\d+)' (.*)" (\w)/.match(latlong).to_a
  calculate_latlong(degrees, minutes, seconds, rotation)
end

def calculate_latlong(degrees, minutes, seconds, rotation)
  calculated_latlong = degrees.to_f + minutes.to_f/60 + seconds.to_f/3600
  ['S', 'W'].include?(rotation) ? -calculated_latlong : calculated_latlong
end


end

所有在所有我想得到的纬度和经度变量更新到数据库从exif提取..提取不是问题,而是我相信我如何保存信息到数据库是真正的问题!谢谢!!!!

All in All i would like to get that latitude and longitude variable updated into the database from the exif extraction.. the extraction isn't the problem but instead I believe how Im saving that information into the database is the true problem!!! thank you!!!!

推荐答案

这个问题似乎是因为您要更新关联模型的属性。您可以通过调用

The issue seems to stem from the fact that you are updating attributes from an associated model. You could do so by calling

update_attributes(place_attributes:{latitude:,longitude:})

但我建议保持这个逻辑不在帖子模型中,这真的是一个关注的表单模型,你将原始用户输入转换为数据库可消费格式。如果您不想向应用程序添加其他图层,请至少将这些方法移到自己的模型中。
每次,你看到一组私人方法调用对方和传递状态,我认为这是一个好的迹象,他们应该为一个类:
所以

But I would recommend keeping this logic out of the posts model, this really is a concern for a form model where you transform the raw user inputs into a database consumable format. If you do not want to add an additional layer to your app at least move these methods to their own model.Everytime, you see a group of private method calling each other and passing state around, I think it's a good sign that they should for a class:So

class LotLangParser

  def initialize(image)
    @image = image
    @exif_data = MiniExiftool.new(image.queued_for_write[:original].path)
  end

  def lat
    parse_latlong(exif_data['gpslatitude'])
  end

  def lon
    parse_latlong(exif_data['gpslongitude'])
  end

  private

  def parse_latlong(latlong)
    return unless latlong
    match, degrees, minutes, seconds, rotation = /(\d+) deg (\d+)' (.*)" (\w)/.match(latlong).to_a
    calculate_latlong(degrees, minutes, seconds, rotation)
  end

  def calculate_latlong(degrees, minutes, seconds, rotation)
    calculated_latlong = degrees.to_f + minutes.to_f/60 + seconds.to_f/3600
    ['S', 'W'].include?(rotation) ? -calculated_latlong : calculated_latlong
  end
end

注意,我还将封装MiniExiftool并将其注入构造函数中的依赖项。

As a note I would also encapsulate MiniExiftool and inject it as a dependency in the constructor. But let's not lose sight of our goal here.

然后在你的控制器中,你可以调用你的解析器给你的地方params

Then in your controller you can call your parser to give you the place params

def place_params
  long_lat_parser = LongLatParser(image)
  {place_attributes: {longitude:  long_lat_parser.lon,  latitude: long_lat_parser.lat}}
end

,然后简单地将它们合并到后期参数中:

and then simply merge them into the post params:

@post = current_user.posts.build(post_params.merge(place_params))

这种方法的好处是,您已经引入了一个明确责任的对象,并作为数据库包装器返回到AR模型。一般来说,我尝试在某种服务对象中封装更复杂的交互,但在简单的情况下,您的控制器可以扮演协调器的角色,协调系统中不同的对象如何交互。

The benenfit of this approach is that you have introduced an object with a clear responsibility and returned to AR model as mere database wrapper. In general I try to encapsulate more complex interaction in some sort of service object, but in the simple case your controller can play the role of mediator orchestrating how different object in your system interact.

这篇关于在PostsController中的NoMethodError#创建未定义的方法`latitude ='“保存lat和long到连接的表”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 08:12