问题描述
我试图将这些坐标从图像的元数据我上传与回形针到另一个表称为地方。所以坐标转到地方表。地方资讯表中有列经纬度。提交后,我遇到这个错误。错误的突出部分是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到连接的表”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!