I want to fetch username or email( both are in user table) of user who creates article in blog application. Currently I am able to fetch user id from articles_controller.rb
def create
#article = Article.new(params[:article])
#article.user_id = current_user.id
#article.save
redirect_to article_path(#article)
end
but no idea how to fetch username or email for same. Basically I want to display username or email on article index page. Please suggest me to how to get done it
user.rb
class User < ActiveRecord::Base
has_many :articles
has_many :comments
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :email, :password, :password_confirmation, :remember_me
attr_accessible :title, :body
end
article.rb
class Article < ActiveRecord::Base
attr_accessible :title, :body
has_many :comments
belongs_to :user
end
articles_controller.rb
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def show
#article = Article.find(params[:id])
end
def new
#article = Article.new
end
def create
#article = Article.new(params[:article])
#article.user_id = current_user.id
#article.save
redirect_to article_path(#article)
end
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to action: 'index'
end
def edit
#article = Article.find(params[:id])
end
def update
#article = Article.find(params[:id])
#article.update_attributes(params[:article])
flash.notice = "Article '#{#article.title}' Updated!"
redirect_to article_path(#article)
end
end
article/index.html.erb
<div style="color:#666666; margin-top:10px"> <%= article.created_at %></div>
<div style="color:#666666; margin-top:10px"> <%= article.user_id %></div>
Articles table
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :title
t.text :body
t.timestamps
end
add_index :articles, [:user_id, :created_at]
end
end
I am able to fetch user id in views but no idea how to username or email.
Any help would be appreciated.
You have defined a user association on your Article model class with belongs_to :user. This creates a user method on Article that returns the associated user so you in your view:
<%= article.user.email %>
will output the email of the associated user, or:
<%= article.user.email if article.user %>
to cater for nil user values. Alternatively write a helper to factor this logic out of the view.
Already you set relation between the Article & User model. So in your article index page you have all articles in #articles variable. So easily you can get the particular user of a particular article using below code,
#articles.each do |article|
user = article.user #gives the user of this current article. From this
#objecct you can easily get the username, email or everything specific to user.
email = user.email #gives email of article's user or you can directly give artile.user.email
end
like this you can get all the attribute of user.
Related
I'm renewing a small library app and my search filter (pg_search) doesn't work with a model that is referenced with another (in this case, model Book as User references, for each user to have it's own set of books).
But if i delete the references, the search works... In the case that if the books were available to every user but that's not the purpose.
What am i missing?
Thanks in advance for any help.
Book.rb
class Book < ApplicationRecord
belongs_to :user
include PgSearch::Model
pg_search_scope :search_by_full_name, against: [:title, :author],
using: { tsearch: { prefix: true } }
validates :title, presence: true
validates :author, presence: true
end
User.rb
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :books
end
books_controller.rb
class BooksController < ApplicationController
def index
if params[:term].present?
#books = Book.search_by_full_name(params[:term])
else
#books = Book.all
end
end
def show
#book = Book.find(params[:id])
end
def new
#user = User.find(params[:user_id])
#book = Book.new
end
def create
#user = User.find(params[:user_id])
#book = Book.new(book_params)
#book.user = #user
if #book.save
redirect_to user_books_path
flash[:notice] = 'Success. Your book was added to the Library'
else
render "new"
flash[:notice] = 'Book not created. Please try again'
end
end
def edit
#user = User.find(params[:user_id])
#book = Book.find(params[:id])
end
def update
#book = Book.find(params[:id])
#book.update(book_params)
redirect_to user_book_path
end
def destroy
#book = Book.find(params[:id])
#book.destroy
redirect_to user_books_path
end
private
def book_params
params.require(:book).permit(:title, :author, :photo, :comments)
end
end
_search_book.html.erb
<%= form_tag user_books_path(current_user.id, #book), method: :get do %>
<%= text_field_tag 'term', params[:term], placeholder: "Enter title or author" %>
<%= submit_tag 'Search!' %>
<% end %>
It's solved... I was using current_user on the views instead of applying all the method on the controller and on the view leave it with only the model instance.
Thanks everyone
I'm currently trying to create a photo in the controller. However, the instance is not being saved. I'm passing the correct parameters but not sure why is not being saved.
18: def create
19: #photo = Photo.new(photo_params)
=> 20: binding.pry
21: if #photo.save
22: redirect_to #photo
23: else
24: render "new"
25: end
26: end
[1] pry(#<PhotosController>)> Photo.new(photo_params)
=> #<Photo:0x00007fefafb9b058 id: nil, user_id: nil, location: "New York", description: "something somethings", created_at: nil, updated_at: nil>
As you can see above the parameters are being passed but not the id and the user_id is nil as well, is it because of the association that is not being built?
class PhotosController < ApplicationController
def index
#photos = Photo.all
end
def show
#photo = Photo.find(params[:id])
end
def new
#photo = Photo.new
end
def edit
#photo = Photo.find(params[:id])
end
def create
#photo = Photo.new(photo_params)
if #photo.save
redirect_to #photo
else
render "new"
end
end
def update
#photo = Photo.find(params[:id])
respond_to do |format|
if #photo.update(photo_params)
format
.html { redirect_to #photo, notice: 'Post was successfully updated.' }
else
format.html { render :edit }
end
end
end
private
def photo_params
params.require(:photo).permit(
:location,
:description,
:image,
)
end
end
Here is the controller for Photos. Here I have new and create. In create I'm passing the params to create the photo. I wonder if I should pass this from the current user due to the following association.
class Photo < ApplicationRecord
has_one_attached :image
belongs_to :user
end
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :photos
has_one :profile
accepts_nested_attributes_for :profile
end
Here I have that the following models. A user has many photos and a photo belongs to the user.
class CreatePhotos < ActiveRecord::Migration[5.2]
def change
create_table :photos do |t|
t.references :user, foreign_key: true
t.string :location
t.string :description
t.timestamps
end
end
end
As far as the migration for photos goes. I don't think I have to add :image to the table since ActiveStorage takes care of that by the has_one_attached method. Not sure what the issue is?
In the default options of
belongs_to :user
require the user_id to be set in current versions of Rails. Because you do not assign a user to the new photo the photo cannot be saved.
To assign the current user to a new photo just change this line
#photo = Photo.new(photo_params)
in your create method in the controller to
#photo = current_user.photos.build(photo_params)
I advise reading the docs about the has_many association in the Rails Guides.
Your photo_params contains only three values:
params.require(:photo).permit(
:location,
:description,
:image,
)
Those are the only values you're passing to Photo.new, so those are the only fields that are being populated. It's unclear why you would expect the user_id to be set, but the id and created_at fields are populated automatically when you save the record. Put your binding.pry after your save call.
I am using the Rails "Getting Started" blog post exercise, and trying to integrate with Devise for authentication and authoring of posts.
When creating an Article, the Author should be the currently logged-in user.
I am getting an error when trying to Create an Article. I know that the error is in my Articles controller, but I can't seem to figure out how to grab the current logged-in Author to kick off the creation of an Article. I believe I did the relationship properly between an Author and an Article.
Error: undefined method `articles' for nil:NilClass
Author Model:
class Author < ApplicationRecord
has_many :articles
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Articles Model:
class Article < ApplicationRecord
belongs_to :author
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5 }
end
Articles Controller:
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def show
#article = Article.find(params[: id])
end
def new
#article = Article.new
end
def edit
#article = Article.find(params[: id])
end
def create
#author = #current_author
#article = #author.articles.create(article_params)
if #article.save
redirect_to #article
else
render 'new'
end
end
def update
#article = Article.find(params[: id])
if #article.update(article_params)
redirect_to #article
else
render 'edit'
end
end
def destroy
#article = Article.find(params[: id])
#article.destroy
redirect_to articles_path
end
private
def article_params
params.require(: article).permit(: title,: text,: author)
end
end
Try removing the # from #current_author. With devise, current_author is a method that returns the user by session[:user_id] not an instance variable.
Also, try doing one of three things....
Change #author.articles.create(atricle_params) to #author.articles.new(atricle_params)
Move the assignment of the author to the 'new' method as so...
def new
#article = Article.new
#article.author = current_user
end
Add a hidden_field to your form...
'<%= f.hidden_field :author_id, current_user.id %>
'
I have two models, User and Company. I have used the device gem for User model creation.
class User < ApplicationRecord
belongs_to :company
accepts_nested_attribute_for :company
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable
end
class Company < ApplicationRecord
has_many :users
end
When I create users, I want to associate with them the company they work in. I have included the company_name attribute in the user creation form. What I don't want is the company table to have multiple records for the same company_name attribute.
<% form_for(#user) do |user_form| %>
<% user_form.fields_for :company do |company_form| %>
<%= company_form.label :company_name %>
<%= company_form.text_field :company_name %>
<% end %>
# other fields for user
<% end %>
I want to check if the company the user is associated with, is already present or not in the company table. Create a new record for the company only if it is not already present.
class User < ApplicationRecord
before_save :create_or_initialize_company
private
def create_or_initialize_company
Company.where("name ILIKE '%#{company_name}%'").first_or_create
end
end
Now here, you can do couple of variations based on your requirements e.g.
If you want exact match then .where(name: company_name)
If you don't want case insensitive match then replace ILIKE with LIKE.
Hope it helps..
class UsersController < ApplicationController
def create
#user = User.new(user_params)
assign_new_or_existing_company(#user)
if #user.save
# ...
end
def update
#user = User.find(params[:id])
#user.assign_attributes(user_params)
assign_new_or_existing_company(#user)
if #user.save
# ...
end
private
def assign_new_or_existing_company(user)
user.company = Company.where(
'company_name ILIKE ?',
"%#{user_params[:company_attributes][:company_name]}%"
)
.first_or_initialize(user_params[:company_attributes])
end
def user_params
params.require(:user).permit(:id, company_attributes: [:company_name])
end
end
As the title suggests, I am building a Q&A application (Like ask.fm) in Ruby on Rails, and I am having some trouble with sending the question to a specific user.
I have 3 models, a User model (from Devise), A Question model with this attribute: content:text and a Answer model with this attribute: content:text
Here are their models
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class Question < ActiveRecord::Base
has_one :answer
belongs_to :user
end
class User < ActiveRecord::Base
has_many :questions
has_many :answers
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
And here are the migrations that I created
This one adds a user_id to the question (So I can check which user sent the question, btw this works fine)
class AddUserIdToQuestion < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
end
Here I tried to add a receiver (the user that would get the question) but I wont work, when I create a Question It will be equal to 'nil', when I check it out in the rails console (Check the controller to see what I did)
class AddReceiverToQuestion < ActiveRecord::Migration
def change
add_column :questions, :receiver, :integer
end
end
Here is the question controller
class QuestionsController < ApplicationController
def new
#question = Question.new
end
def create
#question = Question.new(question_params)
#question.user_id = current_user.id
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id)
end
end
I also have a user profile page where I have a form show up, here is the controller for that one
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#user_questions = #user.questions
#question = Question.new
end
def create
#user = User.find(params[:id])
#question = Question.new(question_params)
#question.receiver = #user.id #This does not work
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id, :receiver)
end
end
I really hope some of you know what I could do here, thank you :)