Displaying Important To Do's In Index View - ruby-on-rails

Fresh learning rails, be gentle. No programming experience, but learning.
Building simple app: An app that asks "what's the most important thing you can do right now," gives you an answer field, submits it, and then displays the stored important things.
Ideally, they won't be stored on the index page, but for learning purposes, I'm trying to get them to do this.
Controller code:
class FacilitatesController < ApplicationController
def index
#facilitate = Facilitate.all
end
def new
#facilitate = Facilitate.new
end
def create
#facilitate = Facilitate.new(params[:facilitates])
#facilitate.save
redirect_to #facilitate
end
private
def facilitate_params
params.require(:facilitate).permit(:answer)
end
def show
#facilitate = Facilitate.find(params[:id])
end
end
Index View code:
<h1>Impactful Task Elicitation</h1>
<h1>Listing Stored To dos</h1>
<table>
</table>
<%= link_to 'Store impactful tasks', new_facilitate_path %>
NEW view code:
<h1>What is the most impactful task?</h1>
<p>Store below, motherbiatch</p>
<%= form_for :facilitate, url: facilitates_path do |f| %>
<p>
<%= f.label :answer %><br>
<%= f.text_area :answer %>
</p>
<p>
<%=f.submit 'Save Task' %>
</p>
<% end %>
So far, I can navigate from index, to facilitates/new, and answer the question, to store my important to do. It then takes me to facilitates/33 (ID I'm assuming, or the number that I'm on, task wise)
I'd like to display these tasks both on the facilitates/33 (or whatever number it ends up being) page, as well as the index page.
I've followed directions on a similar type of form here: http://guides.rubyonrails.org/getting_started.html but, I still can't get my stored To do's to display anywhere.
Any help would be awesome.

In your controller, you have the show method below the private line. That means that it can only be called from inside the controller, so you are being sent to the show template without that method ever being called (#facilitate will be nil).
Move the def show method up above the private line.
It then takes me to facilitates/33 (ID I'm assuming, or the number that I'm on, task wise)
The line redirect_to #facilitate, means that after the facilitate is created, go to it's show method and page. The 33 is just a database reference for that particular facilitate, that it can be looked up again with Facilitate.find(params[:id]).
You didn't post what app/views/facilitates/show.html.erb looks like, but if you want to display the newly created facilitate, then it should have a line like this:
<%= #facilitate.answer %>
I'd like to display these tasks both on the facilitates/33 (or whatever number it ends up being) page, as well as the index page.
If you only care about the listing, and not individual facilitates pages, then after creation you can redirect back to the index in the create method by changing redirect_to #facilitate to redirect_to facilitates_path (which translates to '/facilitates').
EDIT:
The <%= #facilitate.answer %> example was meant for the show view, not index.
On index, you'd do something more like this:
<% #facilitate.each do |facilitate| %>
<%= facilitate.answer %><br>
<% end %>
To list them all.

Related

Render results on #show without storing data in ActiveStorage

I'm learning RoR by building my first app (yay!). I gotta a question thought as rails guides do not cover this topic:
How to render unique results on #show to a user without storing any data in a model?
Steps I want to take:
Create a basic index view with a form_tag that will allow user to submit a link (string) and click submit button
Write Service Objects that will allow me to parse that link and create a response I want user to see
I want to write a #show method in a separate controller that will allow me to display all the data. (I also want to parse my params[:link] in that method using Service Objects.
I want to finally display this data in a table in #show view (probably I need to create a unique #show/[:id] for each user?
Here's what my app looks like at the moment (more or less):
Static Controller (just to render index.html.erb with a form)
class StaticController < ApplicationController
def index
end
end
Static Index view (yup, parsing imgur link here)
<h1>Hello Rails!</h1>
<%= form_tag("/images", method: "post") do %>
<p>
<%= label_tag(:imgur_link) %><br>
<%= text_field_tag(:imgur) %>
</p>
<p>
<%= submit_tag("Get my cards") %>
</p>
<% end %>
Images Controller (where all the magic SHOULD happen)
class ImagesController < ApplicationController
def show
#collection = params[:imgur_link]
#service1 = service1.new(*args).call
#service2 = service2.new(*args).call
...
end
end
Images Show view
Empty as I'm stuck with the Images controller at the moment.
Any help would be more than appreciated.
Thanks!
There is no reason you should put something into storage just in order to display it. If you get to a point when you have the results in your controller, you could just pass them to view in some #variable
As I see, you have set up the form for step 1. If you also have routes.rb call 'images#show' for POST /images, then you will have params[:imgur_link] available in your show action. This should do:
# config/routes.rb
YourApplication.routes.draw do
# ...
post '/images' => 'images#show'
end
Now you have to somehow process that link. Since I don't know what your results should be, I'm going to assume that you have two classes, Service1 and Service2, both of which accept an URL and return collection of results, and both collections hold the elements of the same class. Then you can leave only unique results for your show view, like this:
# app/controllers/images_controller.rb
class ImagesController < ApplicationController
def show
link = params[:imgur_link]
results1 = Service1.new(link).results
results2 = Service2.new(link).results
#results = (results1 + results2).uniq
end
end
Then you can do something with #results in your show view. E.g.
# app/views/images/show.html.erb
<% #results.each do |result| %>
<%= result.inspect %>
<% end %>

How to create new text field

I know this is probably a very basic question but I am brand new to Ruby and kinda in a dead end. I have made a simple little site with profiles and profile pages. But on the profile pages I would like to add a new text field like "Bio" for instance where the user types in a bio about himself and it shows. Im just at a blank on how to create a new text field where people can input this stuff. I know this is basic stuff just stuck and looking for some help or guidance to a tutorial or something. Thank you in advance
Here's an example copied from another answer:
<%= form_for(:ad, :url => {:action => 'create'}) do |f| %>
<%= f.text_field(:name) %>
<%= f.text_area(:text, "", :size => "50x10") %>
<%= submit_tag("Submit") %>
<% end %>
This is kind of a complicated question, once you think about it, because there are so many parts.
Ruby on Rails is built on a architecture, called Model View Controller or MVC. The three parts together make the user interface that is presented to the user.
Models are the actual data, like the User objects, in this case. To create the model, type in this command to the console:
rails g model User bio:text name:string
This will make a basic user model, which only contains two columns, a column for the bio, and a column for their name. Note that this is very uncomplicated, and this can be expanded on a lot, but for now it will do.
Or, if you already have a user model, type in this command to the console:
rails g migration add_bio_to_users bio:text
Next are the controllers, controllers are, in a way, what connect the models and the views, so they manage all of the logic in the back end, like creating new users, or adding bios to their profiles.
You can create the user controller like this (if you do not already have one):
rails g controller Users new
And then, you can add this code to the new file generated, to add the functionality of adding bios (and showing them, too) (and updating other columns as well):
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
render #user
else
render #user # Handle error accordingly
end
end
def show
#user = User.find(params[:user])
end
private
def user_params
params.require(:user).permit(:name, :bio)
end
Now, to the final part, which is the view, which is the actual thing that is presented to the user:
<%= form_for(:user, :url => {:action => 'update'}) do |f| %>
<%= f.text_field(:name) %>
<%= f.text_area(:bio, "", :size => "50x50") %>
<%= f.submit yield(:button_text) %>
<% end %>
Note that this is just a simple view that assumes that you also have a column name in your User model, you can change this accordingly.
And, finally, to show the user, add this to the show view:
<%= #user.bio %>
to show the bio in the show view.
Good luck!

partial from a folder

I'm working along with Railscast 407 (it's a pro/paid episode) where Ryan Bates adds public activity functionality to a site, namely, each activity (create or update recipes or comments on recipes) is displayed in a public feed. At one point in creating the app, he uses the code below to render out a partial from the /views/activities folder, however, he also adds a comment subfolder so the create partial path is like this views/activities/comment/_create.html.erb and the link to it is like this
<%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>
<h1> Activities </h1>
<% #activities.each do |activity| %>
<%= div_for activity do %>
<%= link_to activity.user.name, activity.user %>
<%= render "activities/#{activity.trackable_type.underscore}/#{activity.action}", activity: activity %>
<% end %>
<% end %>
I'm pretty certain I copied his code correctly, but I'm getting this error when I try to follow along, which
The partial name (activities/comment/) is not a valid Ruby identifier; make sure your partial name starts with a letter or underscore, and is followed by any combinations of letters, numbers, or underscores.
However, he doesn't get that error in the episode. Here's a screenshot Here's a screenshot of his directory
Fyi, the actual partial at this stage of the episode looks like this
commented on <%= link_to activity.trackable.recipe.name, activity.trackable.recipe %>
Can you explain why this isn't working for me?
At one point in the episode, Ryan Bates sets the default action to nil in the method that tracks activity (in the application controller)
def track_activity(trackable, action = nil)
current_user.activities.create! action: action, trackable: trackable
end
However, he later changes the default to the parameter action like this
def track_activity(trackable, action = params[:action])
current_user.activities.create! action: action, trackable: trackable
end
If you use the former code, then unless you explicitly declare the action, it'll be nil in the db, and then the view code in the OP will trigger the error. Therefore, it's safer to use the second version of track_activity.
Thanks to comment by #jvnill for pointing this out

ransack search form in header partial: No Ransack::Search object was provided to search_form_for

First of all, I'm new to RoR, so the answer may be obvious, in which case I apologize. I've looked around and haven't found anything that helps.
I'm trying to have a search form at the header of every web page on my app that will search through the names of all my "buckets". Here is the relevant code:
In app/views/layouts/_header.html.erb (within a nav bar):
<% search_form_for #q do |f| %>
<%= f.label :name_cont %>
<%= f.text_field :name_cont %>
<%= f.submit %>
<% end %>
In app/controllers/buckets_controller.rb:
def index
unless params[:q].blank?
#q = Bucket.search(params[:q])
#buckets = #q.result.paginate(:page => params[:page])
else
#buckets = Bucket.find(:all, :limit => 5).paginate(:page => params[:page])
end
end
I understand the last part isn't that great: what I'm trying to do is if I'm just accessing the bucket index page (not by searching), i display the 5 most recently created buckets. When I search for something in the header form, I access the index page but only show the buckets that hit the search. (would a better way to handle it to have a search page separate from my index page?)
I found this issue which is pretty much identical, but I still don't see how I handle #q if every page is going to have the form on it--surely I don't have to alter every controller's every action?
Sorry in advance for any frustration my noobishness my cause you!
As others have said, you need to utilize the ApplicationController's before_filter. Though ernie himself seems not to recommend this, the implementation is simple.
First, use the advanced Ransack options to set your path for your search thusly
#config/routes.rb
resources :buckets do
collection do
match 'search' => 'buckets#search', via: [:get, :post], as: :search
end
end
Second, update your BucketsController to include the following custom action:
#controllers/buckets_controller.rb
def search
index
render :index
end
Nothing yet out of the ordinary. If you currently try to search you will get the error from your original question. Your definition of the variable q is correctly implemented, but you will have to move it to the ApplicationController like so:
#controllers/application_controller.rb
before_filter :set_global_search_variable
def set_global_search_variable
#q = Bucket.search(params[:q])
end
Finally, update your search form to pass in the correct search options
#layouts/_header.html.erb
<% search_form_for #q, url: search_buckets_path, html: { method: :post } do |f| %>
<%= f.label :name_cont %>
<%= f.text_field :name_cont %>
<%= f.submit %>
<% end %>
No, you do not need to edit all your controllers.
You can use ApplicationController for all your "common" controller needs. Read up on it in the guides http://guides.rubyonrails.org/action_controller_overview.html and the API docs http://api.rubyonrails.org/classes/ActionController/Base.html
The key here is, when you generated your new rails app, you'll notice it created the file .../app/controllers/action_controller.rb and that class derives from ActionController::Base. Then, if you again use the rails generator to create a controller for your app, you'll notice your new controller class derives from ApplicationController (not ::Base). That means that the application_controller.rb is the parent controller class for your app. That means everything in it is available to all your app controllers. It's easy to abuse, so be judicious.
Looks like this is not possible. This is a comment from Ernie the gem author.
You'd have to handle the Ransack-required stuff in a before_filter or
(ick) in the view partial itself. If you're putting a search field on
every single part of the site, I'd recommend you strongly consider
whether ransack is the right tool for the job, as well. You might want
some sort of inverted index search setup like sphinx, solr, etc.
https://github.com/ernie/ransack/issues/3

how to connect my model to my app

Hey all,(im a beginner in rails)
i've created a controller that look like that:
class HomeController < ApplicationController
def homepage
end
def showmsg
#postword = params[:p]
end
end
the showmsg view looks like that:
<%= #postword %>
and my homepage view looks like that:
<%= form_tag( {:controller => 'home', :action => 'showmsg'}, :method => "post") do %>
<%= text_field_tag(:p,#postword) %>
<%= submit_tag("post") %>
<% end %>
now i have a form that i can write something in it and it will show on the showmsg view.
i created a model with the param :posts with a :description "text" field too.
MY QUESTION is how do i implement the model in the code so any thing i write will be in a list with the things i wrote before, because now (obviously) anything if i write something its deleting the one i wrote before.
thank you all!
I would argue that you're approach is not very rail's like... so if you're learning rails... you're learning it wrong.
Make a Model. Call it "Message":
rails generate model Message content:string
remember to migrate (hopefully you have your databases setup properly):
rake db:migrate
Then in your controller, when you post, you can create message like this:
def create #instead of showmsg... 'create' is the standard name for this
Message.create(params[:message])
#messages = Message.all
end
This will create the message in the database, and then it will get all the messages out of the database and put them into #messages.
You need to edit your form so that it uses form_for. You need to pass it #message, which is an instance of Message.new that your first controller action created. You should call this new
In your create.erb.html file, you show all the messages like this:
<ul>
<% #messages.each do |message| %>
<li><%= message.content %></li>
<% end %>
</ul>
I actually wouldn't recommend showing all the messages in the create action - it should really happen in the index action and you should redirect... but we need to keep this simple. Just google this or watch some of Ryan's screencasts and you'll get it.
And you're done. This is the "Rails Way" to do things. It's best to learn it the way they want you to learn it.
I would also commend that you format your code properly by indenting, and start naming your methods to be real english. For example, showmsg is bad and show_message is a lot better.
If all of this is totally confusing, then just create a new project, and then type:
rails generate scaffold message content:string
It will basically build the application you want and a lot more. You can just read the code and see how they did it.
Hope it helps.
Your approach is not really rails like so some tweaks and fixes are needed. Suggestions: check rails approach to REST. The following code will work it is a little more rails like, but still not all the way there.
Generate a model
rails generate model Message postword:string
this will generate the model and create the migration necessary to create the table in the database.
Create the table
rake db:migrate
Define a post action
It will save the postword in the database. In your controller:
def create
#message = Message.create!(params[:message])
if #message.save
redirect_to "/home/showmsg"
else
render :action => "/home/homepage"
end
end
Create and instance of Message to use in your form
def homepage
#message = Message.new
end
Fix your form tag
<%= form_for #message, :url => "/home/create" do |f| %>
<%= f.label :postword %>
<%= f.text_field :postword %>
<%= f.submit "Create" %>
<% end %>
Now let's show the words in the showmsg page
In the controller select the postwords from the database:
def showmsg
#postwords = Message.all
end
Showing them: /showmsg.html.erb
<H1>postwords list</H1>
<ul>
<% #postwords.each do |p| %>
<li><%= p.postword %></li>
<% end %>
</ul>
Your routes.rb file will have this routes:
get "home/homepage"
get "home/showmsg"
post "home/create"
Define an attribute :new_text in a way similar to this:
class TheModel
# Virtual writer - everything assigned to this attribute
# will be added to self.text
#
def new_text=(v)
self.text += v.to_s
end
def new_text
"" # This is write-only attribute
end
end
Now, use the field 'new_text' in your form.
Of course, this is a very simple example. You should decide whether you want to add the content on every call to :new_text=, maybe some validation would help, the read accessor may need some care, and so on.
For some good guides which may help you start, see the site http://guides.rubyonrails.org/

Resources