displaying data from database in a partial - ruby-on-rails

I'm pretty new to rails and I can't figure out how exactly to get data from the database and have it show up in a partial. So I have a question_form partial:
<h1>Add question here</h1>
<div class="row">
<div class="col-md-6">
<%= form_for(:question, url: questions_path) do |f| %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose question..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<!-- ref 398, 664 -->
<% end %>
</div>
</div>
I render it in my root_path (staticpages#home). It POSTs to a create action in a Questions controller which saves it to the database. I want to then display all of the questions submitted at once. I know I can do something like:
def show
#questions = Question.all
end
then iterate through #students in show.html.erb. But the problem is I don't want it in a separate page, I want it all to be shown on the homepage as well. How should I do this?

What about adding the instance variable to the show action for your StaticPagesController:
class StaticPagesController < ApplicationController
def show
#questions = Question.all
# ... Code to render pages/:page
end
And then iterate #questions on the view:
<% #questions.each do |question| %>
<%= question.content %>
<% end %>

Related

Error: param is missing or the value is empty:retweet

I am new to Rails. I want to pass parameters to DB via controller, but I receive this error param is missing or the value is empty:retweet. I think the problem is the way of passing parameters in view.
Here is the view
<% for #p in #posts %>
<div class="panel panel-default post-panel">
<div class="panel-body row">
<div class="col-sm-1">
<img src="/avatar.png" class="rounded-img" height="50px" width="50px">
</div>
<div class="col-sm-11">
<p class="post-title"><%= User.find(#p.user_id).username %> <span class="post-creation">- <%= #p.created_at.to_formatted_s(:short) %></span></p>
<p class="post-content"><%= #p.content %></p>
</div>
<div class="col-sm-12">
<p class="post-links">
<span class="glyphicon glyphicon-comment g-links" aria-hidden="true"></span>
**<%= form_for Retweet.new do |f| %>
<%= hidden_field_tag current_user.id, (:user_id) %>
<%= hidden_field_tag #p.id, (:post_id) %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
And here is the Controller
def new
#retweet = Retweet.new
end
def create
#retweet = Retweet.new(post_params)
redirect_to(:back)
end
private def post_params
params.require(:retweet).permit(:user_id, :post_id)
end
end
You should read up some tutorials on basic REST controllers in Rails. Your create action didn't save the retweet.
def create
#retweet = Retweet.new(post_params)
if #retweet.save
redirect_to(:back)
else
render action: 'new'
end
end
Edit: Just noticed your form is all wrong:
<%= form_for Retweet.new do |f| %>
<%= f.hidden_field :user_id, current_user.id %>
<%= f.hidden_field :post_id, #p.id %>
<%= f.submit "Retweet", class:"btn btn-primary"%>**
<% end %>
Mind you that you shouldn't allow settign the user_id like this, it is very easy to change it and thus mess around with your data. Instead you should add this to retweet#create:
#retweet.user = current_user

Using a form to populate a database and land on a page with the information submitted

I have a form on my new view that takes in "url" and "title". When I submit my "url" & "title" I am taken to a blank create view. Ideally I would like to populate my database and land on a page that shows the title and link for that project.
This is my controller as it stands:
class LinksController < ApplicationController
def index
end
def new
#link = Link.new
end
def create
end
end
And this is the form:
<h1> This is New page for links </h1>
<%= form_for(#link) do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How would I go about creating my methods(actions) to populate the database and then render what I am seeking? Ideally I'd like to see the flow behind how to think about the problem and the final code so that I can reverse engineer it.As long as I see it once I should be able to do it on my own next time.
You just have to do this
def create
#link = Link.new(params[:link])
if #link.save
redirect_to #link
else
render :new
end
end
def show
#link = Link.find(param[:id])
end
In routes.rb you will want to make sure you have the routes for this controller and its actions.
resources :links
That will provide you the standard CRUD HTTP methods with matching routes.

Multiple Loops on the same show page

I have a page that displays a users videos that he has posted and also on the same page a users videos that he has voted on.
here is my controller
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
votes = #user.videos_with_votes("created_at desc").page(params[:page]).per_page(12)
end
end
Here is my view for my show page
<div id="videos">
<% #videos.each do |video| %>
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
<% end %>
</div>
I am confused on how to display the videos that the user has voted on in the same way that i am looping the users video posted?
Use an instance variable, e.g.
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
#voted_videos = #user.videos_with_votes("created_at desc").page(params[:page]).per_page(12)
end
end
<div id="voted_videos">
<% #voted_videos.each do |video| %>
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
<% end %>
</div>
If the display of videos and voted videos is the same than you can look to make this code:
<div class="box">
<%= image_tag video.image.url(:threeacross) %>
<%= video.title %>
<%= video.description %>
<%= video.user_id %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
</div>
a partial called _videos.html.erb that can be used for both #videos and #voted_videos.
Store this file (with the above code) in the same directory as the other view files
e.g.
<div id="voted_videos">
<% #videos.each do |video| %>
<% render "videos" %>
<% end %>
</div>
<div id="voted_videos">
<% #voted_videos.each do |video| %>
<% render "videos" %>
<% end %>
</div>
You need to use #votes instead of votes by itself. The # symbol shares the variable with the view layer so that you can do things with it (like loop over it).
there is a concept about instance variable and local variable in rails.
whenever you define a variable with # symbol that particular variable is an instance variable and is accessible across its views and partials.
for eg : #videos = #user.videos.order("created_at desc").page(params[:page]).per_page(12)
here #videos is an instance variable and persists its instance across its scope.
whereas local variables have its scope limited to its loop/boundry. Local variables are preferably used in loops where after the execution of the loop the variable is Garbage Collected and we can again use the same variable name for storing different value.
In your case votes is not accessible in your view as its a local variable, and hence to use this variable in your view you need to define this variable as instance variable (as #votes).

Displaying the last posts image

I am trying to show the image belonging to the last post at the top of my page
with this code:
<%= image_tag #postlast.last.image %>
Instead it shows the correct image but beside every post.
My index function looks like this:
def index
#posts = Post.order("created_at desc")
#postlast = Post.order("created_at DESC").limit(1)
end
Here is the full view:
<%= image_tag #postlast.last.image %>
<%= div_for(post) do %>
<div class="description">
<%= link_to (post.title), post %>
</div>
<div class="description2">
<%= time_ago_in_words(post.created_at) %> ago
<div class="floatright">
#Questions #Answers
</div>
</div>
<% end %>
Any help is appreciated!

why does this form not take data from a model?

I would like to capture email addresses with this form:
I have decided to create a model only for this and use the views and controller for a different model that is serving only static assets (think: newsletter sign-up).
<%= form_for (#signup) do |f| %>
<% if #signup.errors.any? %>
<div id="error_explanation">
<p><%= pluralize(#signup.errors.count, "error") %> prohibited this post from being saved:</p>
<ul>
<% #signup.errors.full_messages.each do |user| %>
<li><%= user %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email_address %><br />
<%= f.email_field_tag :email_address %>
</div>
<div class="actions">
<%= f.submit %>
</div>
How do I get this form to work? I get undefined method signups_path for #<#<Class:0x00000004f1feb0>:0x00000004f09a98> exception, which is understandable (its looking for a SignupsController by convention).
But I want the form to display in a separate controller I call PagesController and send it to the Signup model.
Additional Info:
I tried passing url: pages_path in the form and get the same exception.
# view inside PagesController
<div class="four columns">
<%= render 'form' %>
</div>
#stub of model
class PagesController < ApplicationController
def index
#signup = Signup.new
end
def create
#signup = Signup.new(params[:signup])
end
end
try:
<%= form_for #sighup, :url => {:controller => :pages, :action => :index} do |f| %>
and I hope you didn't forget the
<% end %>

Resources