2

In rails default controller the new method makes an object, and the create method is used later to save that.

I want to set a mod_user field in the DB, without it being input into the form.

Based on this link http://api.rubyonrails.org/classes/ActiveRecord/Base.html I've tried adding the following to my pages controller.

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

or

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

But it is saving as NULL If I put this in the controller and model then I get nil object errors from ActiveRecord

  def new
    @page = Page.new(1)

  def initialize(n_publisher)
    @n_publisher_id = n_publisher
  end

I have attr_accessor :n_publisher_id included in my page model. This works in the console...

>> @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

Here is schema of the pages table

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)

Here is the model

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

Create Action

  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
1
  • Remove this attr_accessor and test in console if it works Commented Oct 1, 2010 at 14:36

5 Answers 5

4

You should never overwrite the initialize method of your ActiveRecord object. Rails is doing a bunch of stuff behind the scenes and it's known to mess things up.

Instead just append your attribute onto your initial params that you're passing in.

So, assuming :n_publisher_id is a real attribute of your AR object (column in the table), something like:

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

should work.

This also assumes that session[:n_publisher_id] is also not nil (otherwise, of course it will be saved as nil in the db)

Sign up to request clarification or add additional context in comments.

9 Comments

Hello. I tried this and the value is still not being set. "page = Page.new(params[:page].merge({:n_publisher_id => 1}))"
Can you show us the db schema as taken from schema.rb ?? If you do, on the command line, Page.new(:n_publisher_id => 1).save does it work? If not then the only reason can be that n_publisher_id is NOT actually part of the db schema.
Just to add to that. Creating a attr_accessor on your class is not the same as actually having that attribute be persistent in the db. It needs to happen when you created the class, likely with a migration. Or you need to update that db table to have the correct column
Hi Brad. The schema is added to the original post.
Page.new(:n_publisher_id => 1) works in the console. I see => #<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: 1, created_at: nil, updated_at: nil, page_name: nil>
|
2

You could also call super in your initialization method.

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

Comments

1

Remove attr_accessor :n_publisher_id from your model. It is column in db, so Rails took care for it. Maybe your attr_accessor overrides something.

7 Comments

Sorry, I thought this was fixed. It's not. After removing the attr_accessor I was able to make and save correctly through the console. But not through the web app. Neither of the following sets the field page = Page.new(params[:page].merge({:n_publisher_id => 1})) or page = Page.new(params[:page]) page.n_publisher_id = 1
Page Create (0.2ms) INSERT INTO pages (fk_issue, dt_created_date, created_at, updated_at, n_status_id, n_publisher_id, dt_offline_date, page_name, dt_published_datetime) VALUES(NULL, NULL, '2010-10-01 14:46:58', '2010-10-01 14:46:58', NULL, NULL, NULL, 'hello', NULL)
Ok, so it is not saving it. Can you add whole create action to your question?
Added - you see I'm trying to set the field two ways, removing either of them or leaving both sets same result
Last two ideas: try using instance variable instead of local variable (rename page to @page), and second idea: restart your server (sometimes it helps). You can also try adding logger.debug @page.inspect in create action before saving and see in log if this value is set.
|
0

Did you verify already that session[:n_publisher_id] has a value != nil?

A quick verification in your controller, try:

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

If all the newly created pages have n_publisher_id == 3, then session[:n_publisher_id] == nil and must be set somewhere in your app.

7 Comments

Hello. I tried this and the saved records still show n_publisher_id as NULL. This is confusing... do I need a hidden field in the form?
Are you sure that you have a n_publisher_id column in your pages table?
Hello, I pasted the schema above
Have you added :n_publisher_id to attr_accesible in your model?
No, I only had attr_accessor :n_publisher_id. I added attr_accessible and it did not make any difference.
|
0

It sounds like session[:n_publisher_id] is nil. Or you are overwriting it somewhere.

If you have the value available in the create action, merge in the params there and you don't need to bother setting it in the new action.

If you only have it available in the new action for some reason, use a hidden field

My gut tells me that you should be setting this explicitly and actually not allowing mass assignment, but I don't know your use case.

2 Comments

I want to set it from a session variable, who was the user logged in that did this action. I'm trying to set it to a number at first... and not getting very far
i think you'll have to be more specific about your error for help. for example, post the request from the rails log, then the controller code that processes that request, and finally the model code for the object being built. with the information you have provided, i think every person who answered has provided good insight

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.