Question

I am working on a rails application that has these classes..

many STOCKS has..

=> many TIME_DELTAS

Now I just created a branch and added devise to the application. Now, I want each user to be able to have their own stock objects, not a shared database of them but user specific has their own set of stocks in their own private session.

Would I be correct in assuming to do this I would need to make the stocks a nested class of user so each user has their own stocks? Is their a guide to doing this easily? Thanks!!

Index

def index
    if current_user
     @stocks = current_user.stocks
    else
     redirect_to new_user_session_path, notice: 'You are not logged in.'
   end
    end

Create

def create
        # XXX Add columns for delta and current standing when we get there
        # they can intiate to nil
        # params['stock'][:user] = current_user
        @stock = Stock.new(stock_params)
        @stock.user = current_user
        if @stock.save
            redirect_to @stock  
        else
            render 'new'
        end
end

Update

def update
        @stock = find_stock


        if @stock.update(stock_params)
            redirect_to @stock
        else
            render 'edit'
        end
    end

Serverlog

Started POST "/stocks" for 127.0.0.1 at 2014-05-04 15:25:15 -0700 Processing by StocksController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"AvtGUf+gPXnpMHNASQK74G+f97Ho4YxkUDEfl+lhZQg=", "stock"=>{"name"=>"Google", "hashtag"=>"goog"}, "user"=>"2", "commit"=>"Create Stock"} User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY "users"."id" ASC LIMIT 1
(0.0ms) begin transaction Stock Exists (0.1ms) SELECT 1 AS one FROM "stocks" WHERE "stocks"."hashtag" = 'goog' LIMIT 1 Stock Exists (0.1ms) SELECT 1 AS one FROM "stocks" WHERE "stocks"."name" = 'Google' LIMIT 1 (0.0ms) rollback transaction Completed 500 Internal Server Error in 6ms

NoMethodError (undefined method attributes' for nil:NilClass):
app/controllers/stocks_controller.rb:21:in
create'

Rendered /Users/nathanielmots/.gems/ruby/2.1.0/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.6ms) Rendered /Users/nathanielmots/.gems/ruby/2.1.0/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.2ms) Rendered /Users/nathanielmots/.gems/ruby/2.1.0/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.1ms) Rendered /Users/nathanielmots/.gems/ruby/2.1.0/gems/actionpack-4.0.3/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (13.5ms)

Was it helpful?

Solution 2

In order to setup 1-M relationship between User and Stock model, you would need to define the association as suggested below:

class User < ActiveRecord::Base
  has_many :stocks
  ## ...
end
class Stock < ActiveRecord::Base
  belongs_to :user
  ## ...
end

After this create a foreign_key user_id in stocks table as below:

Generate a migration for adding user_id reference to stocks table by running:

rails generate migration AddUserRefToStocks user:references

After this run rake db:migrate

NOTE:

make the stocks a nested class of user so each user has their own stocks?

There is no such thing as nested class in Ruby. What you mean probably is how to setup association between User and Stock classes.

UPDATE

Change your new and create actions in StocksController as below:

def new
  @stock = current_user.stocks.build
end

def create
  @stock = Stock.new(stock_params)
  if @stock.save
    redirect_to @stock, notice: 'Stock was successfully created.'  
  else
    render 'new'
  end
end

Also, add a hidden field (within form_for) in the new view of stocks as below:

<%= f.hidden_field :user_id %>

NOTE: Make sure that you permit the field user_id in stock_params method.

OTHER TIPS

Use Active Record Association.

 class User < ActiveRecord::Base
    has_many :stocks
 end
 class Stock < ActiveRecord::Base
   belongs_to :User
 end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top