I created an twiiter like app, where friends can post, but i want a include the name of the person who created the post in the list showing all the post.
here is my code
class PostsController < ApplicationController
def index
#posts = Post.all(:order => "created_at DESC")
respond_to do |format|
format.html
end
end
def create
#post = Post.create(:message => params[:message])
respond_to do |format|
if #post.save
format.html { redirect_to posts_path }
format.js
else
flash[:notice] = "Message failed to save."
format.html { redirect_to posts_path }
end
end
end
end
`
Assuming, of course, that the 'user has many posts' association is set, and the user model has a 'username' field, you can do this in your view :
<% #posts.each do |post| %>
<%= post.user.username %>
<% end %>
Related
For example I have my index view with all objects in database. And instead of clicking on Create button I want to get it done without refreshing the page using Ajax. How to do it? How can I change my controller for this purpose? Thanks in advance.
My controller
class ArticlesController < ApplicationController
before_filter :authorize, only: [:edit, :new, :destroy]
def index
#articles = current_user.articles
end
def show
#article = Article.find(params[:id])
redirect_to users_path
end
def edit
#article = Article.find(params[:id])
end
def new
#article = Article.new
end
def create
#article = current_user.articles.build(article_params)
if #article.save
redirect_to user_articles_path(current_user)
else
render 'new'
end
end
def update
#article = Article.find(params[:id])
respond_to do |format|
if #article.update(article_params)
format.html {redirect_to user_articles_path(current_user), notice: 'Post was successfully updated'}
format.json { head :no_content }
else
format.html {render action: 'edit' }
end
end
end
def destroy
#article = Article.find(params[:id])
#article.destroy
respond_to {|format| format.js }
end
private
def article_params
params.require(:article).permit(:title)
end
end
For the Ajax, you need a form/link/button with remote:true option, a controller action to handle the JS request and a corresponding view page.
#new.html.erb
<%= form_for #article, remote: true do |f| %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<% end %>
<b>List of Articles</b>
<ul id="articles">
<%= render #articles %>
</ul>
As you want it for creating the articles, change your new and create methods like below
#articles_acontroller
def mew
#article = Article.new
#articles = current_user.articles
end
def create
#article = current_user.articles.build(article_params)
if #article.save
respond_to do |format|
format.html { redirect_to user_articles_path(current_user) }
format.js
else
render 'new'
end
end
end
Add a create.js.erb file
#create.js.erb
$("<%= escape_javascript(render #article) %>").appendTo("#articles");
And a _article.html.erb to display the created articles.
<li><%= article.title %></li>
I am newbie to Rails and I have been struggling with this idea that just can't get over my head. For example I have
class Survey < ActiveRecord::Base
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :survey
end
I have created a set of surveys. Now I want to create some questions and assign it to the survey through its foreign key survey_id. In the Question new.html.erb page, I used advanced form to show the Survey ID(I followed this tutorial). It works fine however, when I click submit, it seems like the survey_id doesn't save.
This is my question_controller.rb
def create
#question = Question.create(question_params)
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' }
else
format.html { render :new }
end
end
def question_params
params.require(:question).permit(:description, :date_created, :survey_id)
end
Here is the form:
<%= form_for(#question) do |f| %>
<div class="field">
<%= f.label :survey_id %><br>
<%= collection_select(:question, :survey_id, Survey.all, :id, :description, prompt: true ) %>
</div>
<% end %>
I know in order for this to work, I have to do something like
#question = #survey.questions.create(...)
but I have no idea how to get the #survey instance before the user click on the drop down and select the appropriate survey.
Anyone has any idea on how to do this ??
Your create method should be
def create
#survey = Survey.find(params[:survey_id])
#question = #survey.questions.create(question_params)
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' }
else
format.html { render :new }
end
end
or you can also use filter
class QuestionsController < ApplicationController
before_filter :set_survey, only: :create
def create
#question = #survey.questions.create(question_params)
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' }
else
format.html { render :new }
end
end
private
def set_survey
#survey = Survey.find(params[:survey_id]) || Survey.new
end
end
you have survey objects created and you want them to be associated to questions,
so, on your question's form if you are using select drop-down with survey names to select from then set select options values to survey id. so your question params will contain survey_id parameter with value equal to selected survey's id. and thus Question.create(question_params) will create question with survey_id.
I have implemented a save buttons for jobs and it work fine now i want to list some of the saved jobs in the jobs index page for this i have this code
<h3>Saved Jobs</h3>
<ul>
<% #user.saved_jobs.limit(5).order(:created_at).reverse_order.each do |saved_job| %>
<li><%= link_to saved_job.job.title, saved_job.job.url %>
<span class="delete_button">
<%= link_to "X", saved_job, :method => :delete, :remote => true %></span></li>
<% end %>
</ul>
<%= link_to "see all", saved_jobs_path %>
but when i want access to the jobs index page i get this error undefined method saved_jobs' for nil:NilClass
this my saved_jobs controller
class SavedJobsController < ApplicationController
before_filter :authenticate_user!
def index
#saved_jobs = SavedJob.find_all_by_user_id(current_user.id)
end
def create
#job = Job.find(params[:saved_job][:job_id])
current_user.save_job!(#job)
respond_to do |format|
format.html { redirect_to #job }
format.js
end
end
def destroy
#job = SavedJob.find(params[:id]).job
current_user.saved_jobs.find(params[:id]).destroy
respond_to do |format|
format.html { redirect_to #job }
format.js
end
end
end
and this is my user controller
class ProfilesController < ApplicationController
before_filter :authenticate_user!
def show
#user = User.find_by_slug(params[:id])
if #user
#posts = Post.all
render action: :show
else
render file: 'public/404', status: 404, formats: [:html]
end
end
def index
#users = user_scope.paginate(page: params[:page], per_page: 2)
end
private
def user_scope
current_user ? User.where.not(id: current_user.id) : User.all
end
end
The error suggests that you didn't set #user in your controller action. Can you post the code from your controller?
Update based on controller code:
Your index action in SavedJobsController does not set #user. When you then call #user.saved_jobs.limit(5)..etc... in the view #user is nil, rather than current_user or whatever.
Additionally, you have set #saved_jobs - why not just use that instead of #user.saved_jobs?
for instance:
#in SavedJobsController
def index
#saved_jobs = current_user.saved_jobs.limit(5).order('created_at DESC')
end
and then, in your view:
<% #saved_jobs.each do |saved_job| %>
I am new to rails.I have some confusion about about rails object life cycle.In rails we have the bellow code.
class UsersController < ApplicationController
# GET /users
# GET /users.json
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
# GET /users/1
# GET /users/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
end
# GET /users/new
# GET /users/new.json
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
# GET /users/1/edit
def edit
#user = User.find(params[:id])
end
# POST /users
# POST /users.json
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PUT /users/1
# PUT /users/1.json
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
end
then in the form we have
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
my confusion is in the new action in controller i have #user = User.new
and again in the create #user = User.new(params[:user]).
then in form i have <%= form_for(#user) do |f| %> .
My question is here at the form the #user object actually means waht?
I mean does this #user is going to hit the new action or create action.
If it is going to hit the create action then how this is happening because the form is actually comes from the new action so i can't figure it out how its hitting to the create action .
i know its very simple question.But i dont know how its happening as i am new to rails.
Please help me to make me understand the object flow.
thanks in advance.
The "new" action makes a new object and shows a form for editing it. That form submits to the "create" action because the object has not been saved yet.
If you did
form_for #user
and #user was a previously-saved object, the form would submit to the update action instead.
form_for is a bit magical, like a lot of rails: it does two things:
sets the "action" attribute of the form to point at either "/users" (for create) and "/users/:id" (for update)
in the case of update (ie for objects that already have an id) it also adds a hidden field which triggers the update action: this hidden field will look like this: <input type="hidden" value="put" name="_method">.
Have a look at form_for in your rails api.
It's hitting create action because of the proper form URL. When you run rake routes command, you'll see that POST /users leads to users#create action - and that's the URL in the new form. URL is set (and form fields are generated) properly by Rails because you pass User instance to the form.
I have a form that saves data, but it gets routed to the wrong URL.
If my form is in
localhost:3000/users/1/styles/1
And when I submit the form, I get redirected to this:
localhost:3000/styles/1
and then I get an error:
Couldn't find User without an ID
views/comments/_form.html.erb
<%= form_for [#commentable, #comment] do |f| %>
<%= f.text_area :content, rows: 3 %>
<%= f.submit %>
<% end %>
styles_controller.rb
def show
#user = User.find(params[:user_id])
#style = #user.styles.find(params[:id])
#commentable = #style
#comments = #commentable.comments
#comment = Comment.new
end
comments_controller.rb
before_filter :get_commentable
def new
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(params[:comment])
#comment.user = current_user
if #comment.save
redirect_to #commentable, notice: "Comment created."
else
render :new
end
end
private
def get_commentable
#commentable = params[:commentable].classify.constantize.find(commentable_id)
end
def commentable_id
params[(params[:commentable].singularize + "_id").to_sym]
end
routes.rb
resources :styles do
resources :comments, :defaults => { :commentable => 'style' }
end
Please let me know if there's other information that is needed. Why am I getting rerouted to a different url? My comment does save into my database.
Thank you
If you want to go back to localhost:3000/users/1/styles/1 after creating comment, you should change
if #comment.save
redirect_to #commentable, notice: "Comment created."
else
to
if #comment.save
redirect_to [User.find(params[:user_id]), #commentable], notice: "Comment created."
else
Edit: Should use User that owns the style not current user