【问题标题】:Rails beginner, initialize objectRails 初学者,初始化对象
【发布时间】:2010-10-01 13:37:59
【问题描述】:

在 Rails 默认控制器中,新方法创建一个对象,稍后使用 create 方法保存它。

我想在数据库中设置一个 mod_user 字段,而不是将它输入到表单中。

基于此链接http://api.rubyonrails.org/classes/ActiveRecord/Base.html,我尝试将以下内容添加到我的页面控制器中。

  def new
    @page = Page.new(:n_publisher_id => session[:n_publisher_id])

  def create
    page = Page.new(params[:page])
    page.n_publisher_id = session[:n_publisher_id]

但它保存为 NULL 如果我把它放在控制器和模型中,那么我会从 ActiveRecord 中得到 nil 对象错误

  def new
    @page = Page.new(1)

  def initialize(n_publisher)
    @n_publisher_id = n_publisher
  end

我的页面模型中包含 attr_accessor :n_publisher_id。这适用于控制台...

>> @i = Page.new
=> #<Page id: nil, fk_issue: nil, n_status_id: nil, dt_published_datetime: nil, dt_offline_date: nil, dt_created_date: nil, n_publisher_id: nil, created_at: nil, updated_at: nil, page_name: nil>
>> @i.n_publisher_id
=> nil
>> @i.n_publisher_id = 1
=> 1
>> @i.n_publisher_id
=> 1

这是 pages 表的架构

mysql> show fields from pages;
+-----------------------+--------------+------+-----+---------+----------------+
| Field                 | Type         | Null | Key | Default | Extra          |
+-----------------------+--------------+------+-----+---------+----------------+
| id                    | int(11)      | NO   | PRI | NULL    | auto_increment |
| fk_issue              | int(11)      | YES  |     | NULL    |                |
| n_status_id           | int(11)      | YES  |     | NULL    |                |
| dt_published_datetime | datetime     | YES  |     | NULL    |                |
| dt_offline_date       | datetime     | YES  |     | NULL    |                |
| dt_created_date       | date         | YES  |     | NULL    |                |
| n_publisher_id        | int(11)      | YES  |     | NULL    |                |
| created_at            | datetime     | YES  |     | NULL    |                |
| updated_at            | datetime     | YES  |     | NULL    |                |
| page_name             | varchar(255) | YES  |     | NULL    |                |
+-----------------------+--------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)

这是模型

class Page < ActiveRecord::Base
  has_many :slots, :dependent => :destroy
  accepts_nested_attributes_for :slots

  #attr_accessor :n_publisher_id
  #attr_accessible :n_publisher_id
end

创建动作

  def create
    page = Page.new(params[:page].merge({:n_publisher_id => 1}))
    #page.dt_created_date = Date.today

    page.n_publisher_id = 1

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

【问题讨论】:

  • 删除这个attr_accessor 并在控制台中测试它是否有效

标签: ruby-on-rails ruby


【解决方案1】:

您永远不应该覆盖 ActiveRecord 对象的初始化方法。 Rails 在幕后做了很多事情,众所周知它会把事情搞砸。

而只是将您的属性附加到您传入的初始参数上。

因此,假设 :n_publisher_id 是您的 AR 对象(表中的列)的真实属性,类似于:

@page = Page.new(params[:page].merge({:n_publisher_id => session[:n_publisher_id]}) 

应该可以。

这也假设 session[:n_publisher_id] 也不是 nil(否则当然会在 db 中保存为 nil)

【讨论】:

  • 你好。我试过了,但仍然没有设置值。 "page = Page.new(params[:page].merge({:n_publisher_id => 1}))"
  • 你能告诉我们从 schema.rb 获取的数据库模式吗?如果你这样做了,在命令行上, Page.new(:n_publisher_id => 1).save 有用吗?如果不是,那么唯一的原因可能是 n_publisher_id 实际上不是数据库模式的一部分。
  • 只是补充一点。在你的类上创建一个 attr_accessor 与实际让该属性在数据库中持久化不同。它需要在您创建类时发生,可能是通过迁移。或者您需要更新该数据库表以具有正确的列
  • 嗨布拉德。架构已添加到原始帖子中。
  • Page.new(:n_publisher_id => 1) 在控制台中工作。我看到 => #
【解决方案2】:

你也可以在你的初始化方法中调用 super。

def initialize
  @something = false
  @value_you_set = 0
  super() # NOTE: This *must* be called
end

【讨论】:

    【解决方案3】:

    从您的模型中删除 attr_accessor :n_publisher_id。它是 db 中的列,所以 Rails 照顾它。也许你的attr_accessor 覆盖了某些东西。

    【讨论】:

    • 对不起,我以为这已经解决了。它不是。删除 attr_accessor 后,我能够通过控制台正确制作和保存。但不是通过网络应用程序。以下均未设置字段 page = Page.new(params[:page].merge({:n_publisher_id => 1})) 或 page = Page.new(params[:page]) page.n_publisher_id = 1跨度>
    • 页面创建 (0.2ms) INSERT INTO pages (fk_issue, dt_created_date, created_at, updated_at, n_status_id, n_publisher_id, dt_offline_date, @98 @,dt_published_datetime) 值(NULL,NULL,'2010-10-01 14:46:58','2010-10-01 14:46:58',NULL,NULL,NULL,'你好',NULL)
    • 好的,所以它没有保存它。您可以在您的问题中添加整个 create 操作吗?
    • 已添加 - 你看我正在尝试以两种方式设置该字段,删除它们中的任何一个或保留两个设置相同的结果
    • 最后两个想法:尝试使用实例变量而不是局部变量(将 page 重命名为 @page),第二个想法:重新启动服务器(有时会有所帮助)。您也可以尝试在保存之前在create 操作中添加logger.debug @page.inspect,并在日志中查看是否设置了此值。
    【解决方案4】:

    您是否已验证 session[:n_publisher_id] 的值 != nil?

    在您的控制器中快速验证,尝试:

    def create
        page = Page.new(params[:page])
        page.n_publisher_id = 3
    end
    

    如果所有新创建的页面的 n_publisher_id == 3,则 session[:n_publisher_id] == nil 并且必须在您的应用中设置。

    【讨论】:

    • 你好。我试过了,保存的记录仍然显示 n_publisher_id 为 NULL。这令人困惑......我需要在表单中添加一个隐藏字段吗?
    • 您确定您的 pages 表中有一个 n_publisher_id 列吗?
    • 你好,我把上面的架构贴上了
    • 您是否在模型中将 :n_publisher_id 添加到 attr_accesible 中?
    • 不,我只有 attr_accessor :n_publisher_id。我添加了 attr_accessible 并没有任何区别。
    【解决方案5】:

    听起来session[:n_publisher_id] 是零。或者你在某处覆盖它。

    如果您在创建操作中有可用的值,请在此处合并参数,您无需费心在新操作中设置它。

    如果出于某种原因您只能在新操作中使用它,请使用隐藏字段

    我的直觉告诉我,您应该明确设置它并且实际上不允许批量分配,但我不知道您的用例。

    【讨论】:

    • 我想从一个会话变量中设置它,谁是登录用户并执行此操作。我一开始试图将它设置为一个数字......并且没有走得太远
    • 我认为您必须更具体地说明您的错误以寻求帮助。例如,从 rails 日志发布请求,然后是处理该请求的控制器代码,最后是正在构建的对象的模型代码。根据您提供的信息,我认为每个回答的人都提供了很好的见解
    猜你喜欢
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多