RoR: Meaning of user ||= User.new
If user
is already set this does nothing, otherwise it will assign a new User
object (created with User.new
).
According to David A. Black, author of "The Well-Grounded Rubyist":
x ||= y means: x || x = y
The difference is that x ||= y won't complain if x is undefined,
whereas if you type x || x = y and there's no x in scope, it will.
For some added details, here's the relevant part of parse.y:
| var_lhs tOP_ASGN command_call
{
/*%%%*/
value_expr($3);
if ($1) {
ID vid = $1->nd_vid;
if ($2 == tOROP) {
$1->nd_value = $3;
$$ = NEW_OP_ASGN_OR(gettable(vid), $1);
if (is_asgn_or_id(vid)) {
$$->nd_aid = vid;
}
}
else if ($2 == tANDOP) {
$1->nd_value = $3;
$$ = NEW_OP_ASGN_AND(gettable(vid), $1);
}
else {
$$ = $1;
$$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
}
}
NEW_OP_ASGN_OR
is defined in node.h
:
#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)
NEW_NODE
looks like this:
#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
Looking for NODE_OP_ASGN_OR
leads to compile.c
, where the interesting part looks like this:
case NODE_OP_ASGN_OR:{
LABEL *lfin = NEW_LABEL(nd_line(node));
LABEL *lassign;
if (nd_type(node) == NODE_OP_ASGN_OR) {
LABEL *lfinish[2];
lfinish[0] = lfin;
lfinish[1] = 0;
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
lassign = lfinish[1];
if (!lassign) {
lassign = NEW_LABEL(nd_line(node));
}
ADD_INSNL(ret, nd_line(node), branchunless, lassign);
}
else {
lassign = NEW_LABEL(nd_line(node));
}
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
ADD_INSN(ret, nd_line(node), dup);
if (nd_type(node) == NODE_OP_ASGN_AND) {
ADD_INSNL(ret, nd_line(node), branchunless, lfin);
}
else {
ADD_INSNL(ret, nd_line(node), branchif, lfin);
}
ADD_INSN(ret, nd_line(node), pop);
ADD_LABEL(ret, lassign);
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
ADD_LABEL(ret, lfin);
if (poped) {
/* we can apply more optimize */
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
I think this is more than I ever wanted to know about assignment in Ruby, but it was rather entertaining to look this up.
RoR Devise create user
Try this instead
def create_user
self.user = User.create({ :email => self.email, :password => '123456' })
end
My guess is that the association is not being registered because after the User.new
call the object has not been saved to the database and has not been assigned an id attribute, and the id attribute is what is required to record the association. User.create
initializes the object and saves it to the database in one step (assuming all validations pass).
I have an ldap connection on my RoR app but now how do I check users on login?
You could create a service that handles that process:
app/services/authenticate_user.rb
class AuthenticateUser
def initialize(user, password)
@user = user
@password = password
end
def call
user_is_valid?
end
private
def user_is_valid?
ldap = Net::LDAP.new
ldap.host = your_server_ip_address
ldap.port = 389
ldap.auth(@user, @password)
ldap.bind
end
end
Then use it in your controller:
class SessionsController < ApplicationController
def new
end
def create
username = params[:NumeroEmpregado]
password = params[:password]
name = "Some Name" # Change "Some Name" to set the correct name
if AuthenticateUser.new(username, password).call
user = User.create_with(nome: name).find_or_create_by(NumeroEmpregado: username)
session[:user_id] = user.id
redirect_to '/'
else
flash[:error] = "Erro! \nNúmero de Empregado e/ou password incorrecto(a)"
redirect_to '/login'
end
end
def destroy
session[:user_id] = nil
redirect_to '/index/new'
end
end
AuthenticateUser.new(user, password).call
will return true
when valid user
and password
are provided, and will return false
otherwise.
This is a basic example covering only the LDAP authentication, you will need to adapt it for your specific needs, including exception handling.
What does ||= (or-equals) mean in Ruby?
This question has been discussed so often on the Ruby mailing-lists and Ruby blogs that there are now even threads on the Ruby mailing-list whose only purpose is to collect links to all the other threads on the Ruby mailing-list that discuss this issue.
Here's one: The definitive list of ||= (OR Equal) threads and pages
If you really want to know what is going on, take a look at Section 11.4.2.3 "Abbreviated assignments" of the Ruby Language Draft Specification.
As a first approximation,
a ||= b
is equivalent to
a || a = b
and not equivalent to
a = a || b
However, that is only a first approximation, especially if a
is undefined. The semantics also differ depending on whether it is a simple variable assignment, a method assignment or an indexing assignment:
a ||= b
a.c ||= b
a[c] ||= b
are all treated differently.
Save current user with created object
At first you need add user_id
index to the childrens
table.
Then
If you have login & logout functionalities, I mean session is working currently then how you manage the user session? Something like this?
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
If yes then go to create
method and edit like below
@child = Child.new child_params
@child.user = current_user
@child.save
And remove this .merge(user: current_user)
from child_params
, it will work I hope.
If above solution does not work somehow then pass user_id
manually with form like in the form
<%= f.hidden_field :user_id, value: current_user.id %>
Then the user_id
add to the strong parameters like others attributes.
You can see the test like while user_id
passing properly then what's happening like
Just For Testing Purpose
@child = Child.new child_params
@child.user = User.last
@child.save
Part 2
If you need to give permission to the children_controller
like if user has parent then he/she access to the children_controller
form then create a method like this
before_action :require_parants, only: [:new, :create] # top of the controller
private
# parant column on the users table is boolean true/false
def require_parants
if !logged_in? || (logged_in? and !current_user.parant?)
flash[:danger] = "Only parants can create child"
redirect_to root_url
end
end
The logged_in?
based on this
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
then redirect to the root URL when the user is not a parent.
Hope it helps
Related Topics
Using Poltergeist with a Proxy
How to Update a Model's Attribute with a Virtual Attribute
How to Install Ruby System-Wide Using Rbenv
Rails: Organizing Models in Subfolders Having Warning: Toplevel Constant a Referenced by B::A
Validating Phone Number in Ruby
Spring Doesn't Work. [ Uninitialized Constant Spring::Sid::Dl ]
Rails Not Working for New Project. Showingerror " Superclass Mismatch for Class Cipher (Typeerror)"
What Is the Fastest Way to Sort a Hash
Find and Replace Specific Hash and It's Values Within Array
How to Download File from Google Drive API with Service Account
Ruby Gsub Problem When Using Backreference and Hashes
How to Count Duplicates Hash Itens in Ruby 1.8.5 ( Sketchup Ruby API )
Should Repeat a Number of Times
Uri::Invalidurierror: Bad Uri(Is Not Uri) Testing Rails Controllers
Error While Installing Iconv on Windows by Ruby2.0.0