Ruby on Rails - 将属性添加到ActiveRecord :: Base但不想在数据库中保留,但应该在对象json中

时间:2022-06-15 07:34:56

I have a ActiveRecord::Base model called "Entry". It has a file attached to it. I am uploading files using Paperclip. Now, everything is merry when I using Views and using serverside code in the views. But now, I want to use the JSON and AJAX, render the front end in pure HTML5. So, for that, I will need the URL of the file. But paperclip only stores the file name, file content type etc and I can retrieve the url of the file with,

我有一个名为“Entry”的ActiveRecord :: Base模型。它附有一个文件。我正在使用Paperclip上传文件。现在,当我在视图中使用Views并使用服务器端代码时,一切都很愉快。但是现在,我想使用JSON和AJAX,在纯HTML5中渲染前端。所以,为此,我需要文件的URL。但paperclip只存储文件名,文件内容类型等,我可以检索文件的URL,用,

url = @post.myFile.url

So, I dont want to store the URL seperately in the DB, but want it to be a attribute to the "Post" model, and should be able to set it and get it and also, be the part of my JSON that is sent to the Client side.

所以,我不想将URL单独存储在数据库中,但希望它是“Post”模型的一个属性,并且应该能够设置并获取它,并且也是我发送的JSON的一部分到客户方。

In my controller I have the 'index' method as,

在我的控制器中,我有'索引'方法,因为,

def index
@posts = Post.order("created_at desc")

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @posts }
  end
end

How will I change my Model? How will I change my Controller? I tried using

我将如何更改模型?我将如何更改我的控制器?我试过用

attr_accessor :file_url

in my Model and added the lines to the index method in the controller

在我的模型中,并将行添加到控制器中的索引方法

@posts.each do |myPost|
   myPost.file_url = myPost.myFile.url
end

But could not succeed. Any help will be appreciated. Thank you.

但无法成功。任何帮助将不胜感激。谢谢。

3 个解决方案

#1


0  

I'm not sure I fully understand your goal. Do you want the file_url to be available from each post before you render your JSON? If so, you could do add api_attributes to your model, i.e.:

我不确定我完全理解你的目标。在渲染JSON之前,您是否希望每个帖子都提供file_url?如果是这样,您可以将api_attributes添加到您的模型中,即:

def api_attributes
  {
    id: self.id.to_s,
    title: self.title.to_s,
    ...
    file_url: self.myFile.url,
    ...
  }
end

Then you can render your json with something like:

然后你可以用以下内容渲染你的json:

format.json { render json: @posts.collect{|post| post.api_attributes} }

That will give you all of your Posts with all of the api_attributes you specified. Hope this is what you're looking for.

这将为您的所有帖子提供您指定的所有api_attributes。希望这是你正在寻找的。

#2


0  

There are two issues here: On one hand you were on the right track declaring an attribute accessor. Instead of the loop in the controller define it in your model.

这里有两个问题:一方面,你在正确的轨道上声明一个属性访问器。而不是控制器中的循环在模型中定义它。

def file_url
  myFile.url
end

The second problem is that when you're serializing an array in a controller, it is calling the default serialization of each element, which does not include your virtual attribute file_url.

第二个问题是,当您在控制器中序列化数组时,它会调用每个元素的默认序列化,这不包括您的虚拟属性file_url。

The solution I recommend for this is the ActiveModelSerializers gem, that allows you to easily customize the serialization used by the controller. It's extremely easy to add your virtual attribute. (Note that overriding the as_json method in your model won't work because the array serializer will not use it)

我推荐的解决方案是ActiveModelSerializers gem,它允许您轻松自定义控制器使用的序列化。添加虚拟属性非常容易。 (注意,覆盖模型中的as_json方法将不起作用,因为数组序列化器不会使用它)

#3


0  

You could look into using the RABL gem to control the formatting of your Json output.

您可以考虑使用RABL gem来控制Json输出的格式。

Effectively, it adds view files for Json format, and you can add the URL as a node to the data.

实际上,它为Json格式添加了视图文件,您可以将URL作为节点添加到数据中。

#1


0  

I'm not sure I fully understand your goal. Do you want the file_url to be available from each post before you render your JSON? If so, you could do add api_attributes to your model, i.e.:

我不确定我完全理解你的目标。在渲染JSON之前,您是否希望每个帖子都提供file_url?如果是这样,您可以将api_attributes添加到您的模型中,即:

def api_attributes
  {
    id: self.id.to_s,
    title: self.title.to_s,
    ...
    file_url: self.myFile.url,
    ...
  }
end

Then you can render your json with something like:

然后你可以用以下内容渲染你的json:

format.json { render json: @posts.collect{|post| post.api_attributes} }

That will give you all of your Posts with all of the api_attributes you specified. Hope this is what you're looking for.

这将为您的所有帖子提供您指定的所有api_attributes。希望这是你正在寻找的。

#2


0  

There are two issues here: On one hand you were on the right track declaring an attribute accessor. Instead of the loop in the controller define it in your model.

这里有两个问题:一方面,你在正确的轨道上声明一个属性访问器。而不是控制器中的循环在模型中定义它。

def file_url
  myFile.url
end

The second problem is that when you're serializing an array in a controller, it is calling the default serialization of each element, which does not include your virtual attribute file_url.

第二个问题是,当您在控制器中序列化数组时,它会调用每个元素的默认序列化,这不包括您的虚拟属性file_url。

The solution I recommend for this is the ActiveModelSerializers gem, that allows you to easily customize the serialization used by the controller. It's extremely easy to add your virtual attribute. (Note that overriding the as_json method in your model won't work because the array serializer will not use it)

我推荐的解决方案是ActiveModelSerializers gem,它允许您轻松自定义控制器使用的序列化。添加虚拟属性非常容易。 (注意,覆盖模型中的as_json方法将不起作用,因为数组序列化器不会使用它)

#3


0  

You could look into using the RABL gem to control the formatting of your Json output.

您可以考虑使用RABL gem来控制Json输出的格式。

Effectively, it adds view files for Json format, and you can add the URL as a node to the data.

实际上,它为Json格式添加了视图文件,您可以将URL作为节点添加到数据中。