带有 MYSQL 后端的 Ruby on Rails 中虚拟属性和实例属性之间的区别

发布于 2024-11-29 09:24:53 字数 2022 浏览 3 评论 0原文

我讨厌问这样的新手问题,但我确信我正在做一些根本上错误的事情,而且我很难找到其他同样无能的人。

我的 MCMPART 模型的新视图要求用户输入零件的 :length 和 :width 值。从这些值中,我想导出 :squarefeet (:length * :width/144) 和钣金 :shearsize (:length X :width)。为此,我修改了我的模型,如下所示:

class Mcmpart < ActiveRecord::Base
    belongs_to :sheet
    belongs_to :partloc
    belongs_to :material

    def squarefeet
      self.squarefeet = self.length * self.width/144
    end

    def shearsize
      self.shearsize = [self.length, self.width].join(' X ')
    end

end

控制器只是通用支架,但这里是创建方法:

  def create
    @mcmpart = Mcmpart.new(params[:mcmpart])

    respond_to do |format|
      if @mcmpart.save
        format.html { redirect_to(@mcmpart, :notice => 'Mcmpart was successfully created.') }
        format.xml  { render :xml => @mcmpart, :status => :created, :location => @mcmpart }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @mcmpart.errors, :status => :unprocessable_entity }
      end
    end
  end

为了阐明模型的构造,这里是数据库迁移文件:

class CreateMcmparts < ActiveRecord::Migration
  def self.up
    create_table :mcmparts do |t|
      t.string :partnumber
      t.references :material
      t.references :sheet
      t.references :partloc
      t.decimal :length, :precision => 10, :scale => 3
      t.decimal :width, :precision => 10, :scale => 3
      t.decimal :squarefeet, :precision => 10, :scale => 3
      t.decimal :weight, :precision => 10, :scale => 3
      t.string :shearsize
      t.string :project
      t.boolean :bus

      t.timestamps
    end
  end

  def self.down
    drop_table :mcmparts
  end
end

我相信有人会立即发现我的问题。这正在创建一个虚拟属性,该属性仅在我的 SHOW 视图中显示。但是,我想要的是将 :shearsize 和 :squarefeet 参数添加到我的数据库中。相反,我在数据库中的两个属性都得到了零值。由于它不是我需要的实例属性,因此它不受我的数据库中设置的精度/小数位数值的控制,因此在小数点后显示多达 8 位数字。

我需要在控制器中做些什么吗?我尝试用 @mcmpart.shearsize 替换 self.shearsize 但这只会导致我的页面失败。

感谢第一个指出我的菜鸟错误的人。

谢谢你,

I hate to ask such a newbie question but I am certain that I am doing something fundamentally wrong and I am having a hard time finding others out there who are as clueless.

The NEW view of my MCMPART model requires the user to enter values for :length and :width of a part. From those values, I want to derive :squarefeet (:length * :width/144) and the sheet metal :shearsize (:length X :width). To do this I have modified my model as follows:

class Mcmpart < ActiveRecord::Base
    belongs_to :sheet
    belongs_to :partloc
    belongs_to :material

    def squarefeet
      self.squarefeet = self.length * self.width/144
    end

    def shearsize
      self.shearsize = [self.length, self.width].join(' X ')
    end

end

The controller is just generic scaffold but here is the create method:

  def create
    @mcmpart = Mcmpart.new(params[:mcmpart])

    respond_to do |format|
      if @mcmpart.save
        format.html { redirect_to(@mcmpart, :notice => 'Mcmpart was successfully created.') }
        format.xml  { render :xml => @mcmpart, :status => :created, :location => @mcmpart }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @mcmpart.errors, :status => :unprocessable_entity }
      end
    end
  end

To clarify the construction of the model, here is the database migration file:

class CreateMcmparts < ActiveRecord::Migration
  def self.up
    create_table :mcmparts do |t|
      t.string :partnumber
      t.references :material
      t.references :sheet
      t.references :partloc
      t.decimal :length, :precision => 10, :scale => 3
      t.decimal :width, :precision => 10, :scale => 3
      t.decimal :squarefeet, :precision => 10, :scale => 3
      t.decimal :weight, :precision => 10, :scale => 3
      t.string :shearsize
      t.string :project
      t.boolean :bus

      t.timestamps
    end
  end

  def self.down
    drop_table :mcmparts
  end
end

I am sure someone will spot my problem right away. This is creating a virtual attribute that displays just find in my SHOW view. However, what I want is for this to add the :shearsize and :squarefeet params to my database. Instead I am getting a nil value for both attributes in my database. And since it is not an instance attribute as I require, it is not governed by the precision/scale values set in my database and therefore displays as many as 8 digits after the decimal point.

Is there something I need to do in the controller? I have tried to replace self.shearsize with @mcmpart.shearsize but that just causes my pages to fail.

Kudos to the first person to point out my rookie error(s).

Thank you,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

轻拂→两袖风尘 2024-12-06 09:24:53

基于以下假设,我正在尝试解决您的问题。

  1. 长度和宽度不是数据库属性。
  2. Mcmpart 模型与您提供的一样。

首先将这些线添加到您的 Mcmpart 模型中

before_save :prepopulate #being dumb here, name anything you want but not attribute name like you already did.
attr_accessor :length, width

private

def prepopulate
  self.squarefeet = self.length * self.width/144
  self.shearsize = [self.length, self.width].join(' X ')
end

,这就是添加这些线后您的模型应该是什么样子。

class Mcmpart < ActiveRecord::Base
  belongs_to :sheet
  belongs_to :partloc
  belongs_to :material

  before_save :prepopulate 
  attr_accessor :length, :width

  private

  def prepopulate
    self.squarefeet = self.length * self.width/144
    self.shearsize = [self.length, self.width].join(' X ')
  end
end

这现在应该可以工作了。如果没有,那么我需要更多细节,因为我不清楚。如果能贴出controller和model(完整代码)就更好了。

Based on following assumption I am trying to solve your problem.

  1. length and width are not DB attributes.
  2. Mcmpart model is as it is you provided.

First add these lines to your Mcmpart model

before_save :prepopulate #being dumb here, name anything you want but not attribute name like you already did.
attr_accessor :length, width

private

def prepopulate
  self.squarefeet = self.length * self.width/144
  self.shearsize = [self.length, self.width].join(' X ')
end

So this is how your model should look like after these additions.

class Mcmpart < ActiveRecord::Base
  belongs_to :sheet
  belongs_to :partloc
  belongs_to :material

  before_save :prepopulate 
  attr_accessor :length, :width

  private

  def prepopulate
    self.squarefeet = self.length * self.width/144
    self.shearsize = [self.length, self.width].join(' X ')
  end
end

This should be working now. If it does not then I need more detail as it is unclear to me. It would be better if you can post controller and model (complete code).

夜光 2024-12-06 09:24:53

我能看到你的困惑
shehersize 和 squarefeet 都是计算值,对吗?
他们在你的观点中发挥作用,对吗?

那么您想要将它们存储在数据库中的唯一原因是为了可以正确地格式化它们?

如果上述假设正确,那么您不需要将它们存储在数据库中,您可以在计算它们时对其进行格式化,并且有各种视图助手来限制显示的小数位数。

我不知道你想显示多少个小数点,但如果你想显示 2 个小数位,你可以尝试将

def squarefeet
  self.squarefeet = self.length * self.width/144
  "%.2f" % self.squarefeet %>
end

def shearsize
  self.shearsize = [self.length, self.width].join(' X ')
  "%.2f" % self.shearsize %>
end

.2f 更改为 .4f,如果你想要 4 个小数位,或者你想要的任何小数位,

如果你有如果有其他原因将数据存储在数据库中,那么我建议您使用保存过滤器并在其中进行计算。如果您想了解更多信息,请询问

I can see your confusion
sheersize and squarefeet are both calculated values right?
They work in your views right?

So the only reason you want to store them in your database is so that you can format them right?

If the above assumptions are correct then you don't need to store them in your database you can format them as you calculate them and there are various view helpers to restrict the number of decimal points shown.

I have no idea how many decimal points you want to show but if you wanted to show 2 decimal places you could try this

def squarefeet
  self.squarefeet = self.length * self.width/144
  "%.2f" % self.squarefeet %>
end

def shearsize
  self.shearsize = [self.length, self.width].join(' X ')
  "%.2f" % self.shearsize %>
end

change .2f to .4f if you wanted 4 decimal places or whatever number of decimal places you want to have

If you have other reasons for storing the data in the database then I suggest you use an on save filter and do the calulations in there. If you want more info on that then ask

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文