rails store current user email in database on form submit - ruby-on-rails

I have a column in my database called 'email'. I want to store the current logged in user's email address into this column when they submit a specific form.
At first I thought I should write something in the html to grab the current user's email address and hide it in the form somewhere but I realized that was probably a bad idea since anyone would be able to modify the html to put any email address that they want in there.
So my question is, would I go about this in the controller? If so, how would I go about doing that?

I'm naming that other model as Article(you can use yours)
Have a column called user_id instead of email in that table
Class User
has_many :articles
end
Class Article
belongs_to :user
end
class ArticlesController
def create
#article = current_user.articles.new(article_params)
#article.save
end
def article_params
params.require(:article).permit(:field1, :field2)
end
end
If you do something like this then automatically user_id will be saved in that table.
So it will be easy for you to get all articles which is belonged to that user.
user = User.first
user.artciles # you will get all articles belonged to that user
article = Article.first
article.user # you will get user of that article
Hope this helps

Figured it out
#request.email = current_user.email
#request.save

Related

Attaching default params with a form

In order for a user to use my search form, they type a user's name, press submit, then rails brings up that user's homepage. I am still a beginner, and the "homepage" the user arrives is a response to the GET method pointed at the URL http://localhost:3000/center/show_user?utf8=%E2%9C%93&name=test&commit=Search when I type the user name "test" in the search box.
In the controller action center#show_user, I have set #user = User.find_by(name: params[:name])
and in the view, it displays well with <%= #user.name %>.
I would like to make a form on the center#show_user page for creating a new "item". An item is defined at belonging to the user in the scheme and a user is defined as owning many items (a user has an item_id column and an item has a user_id column).
When this form is submitted, how do I include with it the current user_id, inherited from the params in the url on the page hosting the form? For example, if I go to the page of the user named "sample_user", I want to be able to submit a "new item" form and have the user_id automatically included along with that form.
'Central' controller code for this page is
def show_user
#user = User.find_by(name: params[:name])
end
Just add
<%= hidden_field_tag "user_id", current_user.id %>
to form.
You should create the "item" through the relation with the user. That means:
Given this in your user model:
class User < ActiveRecord::Base
has_many :items
end
Do the following in the controller:
def create
#user = User.find_by(name: params[:name])
#user.items.create(params[:item])
# redirect_to or something different...
end
This will automatically build the relation for you (basically filling in the user_id field for you). The reason for doing it this way is that users can't mess with your form and fill in other user ids in the hidden field.

Rails: how to access questions associated with a user?

I am associating questions with users. Users has_many questions, and questions belongs to users. If I want to show on a user home page their own questions and only edit their own questions, how do I go about verifying this? I think a helper method is required to check whether the question does belong to the user and then, for example, (If question.belongs to user) then show edit link. Any ideas are appreciated!
Limit the scope of your find to the user whose questions you want to search.
Basically...
class QuestionsController < ApplicationController
def show
# instead of this...
#question = Question.find(params[:id])
# do this:
#question = current_user.questions.find(params[:id])
end
end
For showing a user's own questions you can make use of the collection rendering:
<%= render current_user.questions %>
Make sure you have a questions/_question.html.erb view, this is called by rails with a local variable passed to it (as the name of the model e.g. question).
This will only show the questions associated with the user.
edit
To add on meagars answer, you should redirect if the user tries to edit a question which doesn't belong to the user:
redirect_to :root if #question.blank?
Optionally show a notification to the user that they haven't got permission.

Rails 4 and Devise: add custom var at current_user

How can i customize current_user adding an attribute like current_user.array ?
EDIT: better explaination
I need to save the records ids of an associated table cause i dont wanna call the db every time a user visit a page like products/1 to control if the product is associated at the current_user. With the ids i can do something like if the array stored in session[:ids] contain params[:id] current_user can access to the page else redirect_to root_path
current_user is just a Devise helper for the attributes of the currently signed-in user
Adding extra attributes to the object this helper represents will have to be done through the User model:
#app/models/user.rb
Class User < ActiveRecord::Base
has_one :profile
end
#-> current_user.profile.image
In devise current_user refers to the user currently logged in. By using current_user.something you can access the value stored in something. something could be a column in the user table or simply an attribute in the model for storing values.
If you want to store some values for the user only as long as the user is logged in, you can store it in session by using
session[:something] = #Value of something
You can access this value by using session[:something].
Why do you use the session? It is already associated with the current user. For example
Try this in your controller:
session[:array] = #something...
just add the attribute to your user model
You can access the columns in th users table using current_user, but the attributes must be accessible.
current_user.name where name is in the users table and it is attr_accessible in User.rb

Conditional email trigger on Model attribute update (Devise & Rails)

I'm still learning Rails, and using Devise. Currently I am working on a bug/ticket logging system. I'n this system we have tickets created by a user, assigned to another user and all users that can view it can post a reply on it.
I want to trigger an email when a user changes the status of a ticket to closed.
HOWEVER, if you are the creator (of the ticket) and you closed it, you do not want an email, but you want to email the user its assigned to. Likewise, if you are the assignee and you close it, you do not want to email, but you do want to email the creator. If you are neither creator or assignee, you still do not want an email, but you do want to email the other two.
The email will be a small notification noting ticket #_ is closed.
I am a bit tripped up as to where this code should go. There is no new code in the controller but I added a before_update :email_update in my ticket model.
def email_update
#status field is changed
if status_changed? && status.description == "Closed"
if(current_user != assigned_to)
UserMailer.new_ticket_admin(assigned_to, self).deliver
end
if(current_user != user)
UserMailer.new_ticket_admin(user, self).deliver
end
end
end
But, is this not bad practice to access the current user in one of the models? What would be a better approach?
Pretty sure, but I don't think that you can access current_user in the model. Even if you could, might I suggest an alternative. Instead, I would use a closed_by_id attribute where it is the current_user's ID. This way you can also track who closed a ticket. From here, you can check to see if the ticket is closed and if the creator of the ticket's ID is equal to the closed_by_id.
As you mentioned you have a creator and a 'closer' (or whatever you want to call that user). Within your user model you want to have something like this:
class Ticket < ActiveRecord::Base
belongs_to :requested_by, class_name: 'User' # foreign_key requested_by_id
belongs_to :closed_by, class_name: 'User' # foreign_key closed_by_id
def close(user)
self.closed_by = user
self.save
end
# bonus method
def closed?
closed_by?
end
end
def User < ActiveRecord::Base
has_many :tickets, foreign_key: 'requested_by_id'
has_many :closed_tickets, foreign_key: 'closed_by_id'
end
And for your controller something like:
class TicketController < ApplicationController
def create
#ticket = current_user.tickets.build params[:ticket]
end
def close
#ticket = Ticket.find(params[:id])
#ticket.close current_user
end
end
This way there is no need to have current_user within your model. Which probably solves your challege.

anonymous and registered user implementation with acts_as_commentable?

I am using acts_as_commentable and am curious if anyone has any good ideas on how to allow for anonymous and registered users to post comments? Meaning, if a registered user is authenticated, I want the comment to be marked with their name, etc. But I also want an anonymous user to be able to comment and have a name and email address recorded. I am using Devise for authentication.
I have an idea on how to make this work but it feels a little hacky to me. Wondering if anyone has any thoughts.
I don't know your plugin, but if you use this one (https://github.com/jackdempsey/acts_as_commentable), it seems very basic...
The Comment model has a relation to a user which is not mandatory.
So in your new comment form, I would just add two text_field_tags if the user is not logged (text_field_tag :first_name, text_field_tag :last_name).
And I'd just write the create action for comments like this :
def create
#comment = Comment.new(:commentable => #your_object, :user => current_user, :first_name => params[:first_name], :last_name => params[:last_name])
...
end
if the user is not logged, current_user will be nil and that won't cause any problem.
You can write an helper method to display the name for a comment depending it has a user or not like this...
# Displays the user's login if any or else the first name and last name
def displayed_name(comment)
comment.user ? comment.user.login : "#{comment.first_name} #{comment.last_name}"
end

Resources