开发者

What does first.user = current_user mean/do and why is it working?

To start, I have 3 Models:

Location has_many :products
User has_many :products
Products belongs_to :user, :location

Now i have a nested form:

<%= nested_form_for @location do |f| %>
<%= f.error_messages %>
.............
<% f.fields_for :products do |product| %>

I was trying to find the right way to get my current_user association to work and suddenly out of pure chance found the right answer in this question, Nil foreign key in a nested form.

I put this piece of simple code in my controller and it finally gave my products to the current user_id:

@location.products.first.user = current_user

full -

def create
    @location = Location.new(params[:location])
    @location.products.first.user = current_user
end

My end goal was accomplished. Users have their own products created 开发者_高级运维at the specific location. Only thing i don't understand is why first.user = current_user works and something simple like location = @location.current_user.products.build doesn't. Could someone give me a great explanation on whats going on here and what the former means? Is this OK to have or is their a safer/better way?

Thank you, i do appreciate it.


The simplest way to define current_user is

class ApplicationController < ActionController::Base  
  protect_from_forgery  
  helper_method :current_user  

private  
  def current_user  
    @current_user ||= User.find(session[:user_id]) if session[:user_id]  
  end  
end 

so current_user is defined inside ApplicationController class whenever you trying to do

@location = Location.new(params[:location])
@location.current_user 

you're trying to call method defined in other class as a method of the Location instance


During this statement

@location.products.first.user = current_user

Rails, by default, assigns the id of the current_user to the left hand side. It is made possible by the internal call to the to_param. You can even override that method to return something else, even random stuff, but it wont be helpful :)

regarding the @location.current_user.products.build, this will not work because location and user are not related, if you want to make this work, you can do it by building a product in the new method and passing the current user id as a parameter to the method.

def new
  @location = Location.new
  @location.products.build
  respond_to do|format|
    format.html
  end
end

UPDATE: I accept tumtu's comment, it is not advisable to put the user id as a hidden element.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜