i did a button in html that when you press it send to the controller the current_user, so after that i want to work with that user in the controller but when i try to access to the atribute of the object user appears a problem saying that my object user is a string and a really don t know how trasform it to a object again, this is my code and the error:
Error:
NoMethodError in ArticlesController#show
undefined method `id' for "#<User:0x00007fe6d52c9c50>":String
Extracted source (around line #66):
puts params[:petition] user = params[:petition] puts user.id # user = User.find(params[:petition]) # puts datos.email # $list_of_petition.push(user)
code of the html:
<!--hacer boton de peticion-->
<form action=<%article_path(#article)%>>
<label for="petition">mail del usuario que se <br> convertira en moderador:</label>
<button name="petition" value=<%=current_user%> type="submit">pedir moderar</button>
</form>
code of my Articlescontroller:
def show
#article = Article.find(params[:id])
#posts = #article.posts
puts "fijate men"
puts params[:q]
puts params[:petition]
if params[:q] != nil
#answer = Search()
puts "aqui deveria ir respuesta"
puts #answer
end
if params[:petition] != nil
puts "miar aqui plspslpsl"
puts params[:petition].inspect
#respond = ask_to_admin()
end
end
def ask_to_admin
puts "hola"
puts params[:petition]
user = params[:petition]
puts user.id
i know that there is a way replacing the current_user for current_user.idand after in the controller make user = User.find(params[:petition]) but i dont what that, what to send the whole user.
In your code user=params[:petition] means assigning user variable a string.
You can't pass current_user through params. Instead, you should pass the current_user.id and in your controller, you can do something like below:
user = User.find params[:id]
Always remember params is an instance of ActionController::Parameters and behaves like a hash object and when you try to pass current_user or any other record within params, Actually you're just passing a String. So always pass the record id in params
Related
Rails 5.2
In my inventories_controller.rb, I have the following:
before_action :fetch_product, only: [:show]
def show
........
end
def fetch_product
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
This works fine, when I do: http://0.0.0.0:3000/sku/12345678
I am trying to implement search functionality, so I modified nventories_controller.rb as follows:
def fetch_product
if params.has_key?(:search) && !params[:search].blank?
product = Product.find_by_sku(params[:search])
if !product
params = params.except[:search]
redirect_to product_show_path, alert: 'Product was not found'
end
params = params.merge!(:sku, product.sku)
end
if params.has_key?(:sku)
#product = Product.get_product(params)
end
end
When I do: http://0.0.0.0:3000/sku/12345678
I get an instant error message:
undefined method `has_key?' for nil:NilClass
Using my debugger, I find that on entry into the fetch_product method, params is nil
Any idea what's going on?
params = params.merge!(:sku, product.sku) modifies the hash in place and returns nil, don't do that assignment, just call params.merge! (if you still want to do the assignment, remove the "!").
Personally, I wouldn't modify the params hash unless it's really really needed, I would use another variable.
I have a Rails 3 blog. I want every Post to have a "Like" button. Clicking on it will save this action to the database and store to cookies on the user who has just liked the Post (for disallowing same action again).
I wrote a simple action to do this:
def like
render :nothing => true
id = params[:post_id]
cookies.permanent[:like_history] ||= []
unless cookies.permanent[:like_history].include? id
cookies.permanent[:like_history] << id
#post = Post.find(id)
#post.update_column(:likes, #post.likes + 1)
end
end
But I'm getting NoMethodError (undefined method '[]' for nil:NilClass) when I try to log things. It points to this line: cookies.permanent[:like_history] ||= [] as if cookies.permanent isn't an array.
Am I doing something wrong with cookies here?
Turns out, the ||= operator counts as "reading" by rails standards, which actually makes sense. You can't "read" with cookies.permanent[:symbol], that's for writing, you read with cookies[:symbol]. So I modified that line to read:
cookies.permanent[:like_history] = "" unless defined? cookies[:like_history]
I think you have something stored in cookies.permanent[:like_history] which is not an Array. So make it nil or covert to array using to_a and try your code.
def like
render :nothing => true
cookies.permanent[:like_history] = nil #or cookies.permanent[:like_history] = cookies.permanent[:like_history].to_a
id = params[:post_id]
cookies.permanent[:like_history] ||= []
unless cookies.permanent[:like_history].include? id
cookies.permanent[:like_history] << id
#post = Post.find(id)
#post.update_column(:likes, #post.likes + 1)
end
end
Once it works remove that line you added.
I have a route that matches /edit_account => accounts#edit since the account id isn't provided it's supposed to use the current user id and the account#edit method is shared with /accounts/[:id]/edit.
class AccountController < ApplicationController
...
def edit
# This doesn't work:
params = retrieve_id_if_missing(params)
# This works:
# aHash = params
# params = retrieve_id_if_missing(aHash)
end
def retrieve_id_if_missing(params)
# raise params.inpect => returns nil at this point
if params[:id].nil? and !logged_in?
redirect_to root_path
else params[:id].nil?
params[:id] = current_user.id
end
params
end
end
The problem I am having is that params, when passed to the class method, retrieve_id_if_missing, is becoming nil. However, if I assign params to another variable. e.g., aHash, before passing it to retrieve_id_if_missing it will contain the expected data, {"action" => "edit", "controller" => "account"}.
I've tried to search for a reason but have come up short, can someone explain to me why this is happening?
Have you tried
class AccountController < ApplicationController
...
def edit
retrieve_id_if_missing
end
def retrieve_id_if_missing()
if params[:id].nil? and !logged_in?
redirect_to root_path
else params[:id].nil?
params[:id] = current_user.id
end
params
end
end
I am fairly sure params will be in scope in the method.
Anyhow, check out gem devise for this. it should have everything you want and more
With devise you can just use
before_filer :authenticate_user!
At the top of your controller
https://github.com/plataformatec/devise
The Ruby interpreter is treating params as a local variable and initializing it with nil when it sees the assignment. This happens before it executes the retrieve_id_if_missing.
This is why explicitly assigning a value to the local variable before calling the method avoids the error, because the initialization to nil by Ruby doesn't happen.
The following examples demonstrate this:
Example #1
def foo(bar)
puts "foo bar: #{bar.class}"
end
bar = foo(bar) # => nil
puts "bar: #{bar.class}"
# Outputs:
# foo bar: NilClass
# bar: bar: NilClass
Example #2
a = a # => nil
puts "a: #{a.class}"
# Outputs:
# a: NilClass
Example #3
a = 123 if a # => nil
puts "a: #{a.class}"
# Outputs:
# a: NilClass
References:
Why is a = a nil in Ruby?
Ruby interpreter initializes a local variable with nil when it sees an
assignment to it. It initializes the local variable before it executes
the assignment expression or even when the assignment is not reachable
(as in the example below). This means your code initializes a with nil
and then the expression a = nil will evaluate to the right hand value.
a = 1 if false a.nil? # => true The first assignment expression is not
executed, but a is initialized with nil.
Ruby: method inexplicably overwritten and set to nil
Here's another example:
a = 123 if a # => nil a # => nil We shouldn't be able to say if a
because we never set a, but Ruby sees the a = 123 and initializes a,
then gets to if a at which point a is nil
I'd consider it a quirk of the interpreter, really. Gary Bernhardt
makes fun of it in wat (https://www.destroyallsoftware.com/talks/wat)
with a = a
While I cannot answer why your params object would be overridden with the code provided, here are some thoughts.
class AccountController < ApplicationController
before_filter :retrieve_id_if_missing, only: :edit
def edit
# You'll find params[:id] prepopulated if it comes here,
# else the request has been redirect
end
protected
# There should be no need to pass the params object around, it should be accessible everywhere
def retrieve_id_if_missing
if logged_in?
params[:id] ||= current_user.id # conditional assignment will only happen if params[:id] is nil
end
# Redirect to root if params[:id] is still blank,
# i.e. user is not logged in and :id was not provided through route
if params[:id].blank?
flash[:alert] = 'You need to be logged in to access this resource.'
return redirect_to root_url # early return!
end
end
end
I inherited a Rails 2.2.2 project that has a form with no server-side form validation so I am trying to add it.
Is there a way to pass the POST variables from the submit_request method below back to the signup method (also below)?
All I am trying to do is repopulate the form with whatever was entered, along with the form validation error message:
class LoginController < ApplicationController
## The controller that displays & processes the form
# Form view
def signup
#hide_logout = "YES"
end
#Form validator/processor
def submit_request
#hide_logout = "YES"
#name = (params[:name] ? params[:name] : "")
#email = (params[:email] ? params[:email] : "")
...
## Validate posted values here
## Build error message, if needed
if(error_str !="")
flash[:warning] = error_str
redirect_to :controller => "login/signup" and return
end
end
end
Then, in the form view grab the POSTED values and populate the form:
<%= text_field_tag("name", (#name !=nil ? #name.to_s : nil), :size => 40) %><br><br>
I guess you just want to display the signup page so do:
def submit_request
#hide_logout = "YES" #why don't you use boolean here?
#name = params[:name] || ""
#email = params[:email] || ""
...
## Validate posted values here
## Build error message, if needed
unless error_str.blank?
flash[:warning] = error_str
render :signup and return
end
end
Bonus: I corrected some code syntax to make it lighter.
Hi I want to send emails to all the email comma addresses entered in text field. I have following controller for doing so.
def send_invites #friend invites
#emails_txt = params[:emails_txt]
#emails = #emails_txt.split(/\s*,\s*/)
#ve = []
#emails.each do |email|
if email =~ /\b[A-Z0-9._%a-z-]+#(?:[A-Z0-9a-z-]+.)+[A-Za-z]{2,4}\z/
#ve << email
end
end
#all_ok = true
#errors = []
#ve.each do |email|
#invitation = Invitation.new
#invitation.sender = current_user
#invitation.recipient_email = email
if #invitation.save
UserMailer.invitation_notification(current_user, #invitation, new_user_registration_url+"/#{#invitation.token}").deliver
else
#all_ok = "false"
#errors << #invitation.errors
end
end
end
It was working fine but now it is giving error as follows
NoMethodError in InvitationsController#send_invites
undefined method `username' for nil:NilClass
whats the problem please help me. Thank you
It looks like you are perhaps referencing a nil object in your email view.
I would look in your view for the UserMailer#invitation_controller action and see where you reference username.
Then, once you found that, trace back the object and find out why its nil, then add some testing around that (i.e. if current_user.nil? ...).