What all models/controllers are needed for building a counter - ruby-on-rails

I want to create a counter example where in the variable increments when ever the user presses a button on the webpage(view)
I have created the ruby program for the counter like this:
def counter(x = 0)
x+=1
puts "The current value is #{x}"
end
I have saved this as counter.rb. Then for the view I created another file called counter.erb But I dont know where to call this rb file and should I use <%= %> embedded ruby tags? Totally confused.
Another thing is the method counter's parameter should be linked to the button clicks.
Please guide me
Thanks,

Ok this is basic and you should be knowing this but still, I will tell you. The question is also vague so I will assume that you have a counter which is a number and a name for the counter. This is how you update any column from scratch.So first create
rails generate scaffold counter count:integer name:string
After this step.
def update
#counter = Counter.find(params[:id])
if #counter.update_attributes(params[:counter])
redirect_to #counter, :flash => { :success => "Profile updated." }
end
end
After this create a view in edit.html.erb under views:
<%= form_for(#counter) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :count %><br />
<%= f.text_field :count %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
Go to counter.rb model and do the following:
class Counter < ActiveRecord::Base
attr_accessible :count, :name
end
You dont have to add anything in the routes file because it already has the update resource.
Now open the browser and if you say
localhost:3000/counter/1/update
after creating the first counter value then you can update stuff from there.
This is how you updating can be done in ruby on rails. If you need more explanation regarding your code you should check the api documentation for rails it is a good start. I am a beginner too.

Looks like you are lacking basic understanding of Rails and MVC. I suggest you start with a simple tutorial to get a grasp on how things are working.
http://guides.rubyonrails.org/getting_started.html will get you started with a simple app and also explains everything you need to know at the beginning.
Basically said, you need a CounterController and - if you want to persist your counter - a Counter model. or you could use a cookie.
However, I advise you to read the guide I posted above.

Related

Creating a Model in Rails within the controller of a different Model

I'm trying to implement a quote saving feature in a Rails app. I have a User Model that has_many :quotes and a Quote Model that belongs_to :user. Now I have a separate Book Model that would be the source of these quotes.
Within the Book's show.html.erb file, I have a form to save quotes for the current user
<%= form_for (#new_quote) do |f| %>
<div class="field">
<%= f.hidden_field :book_id, :value => #new_comment.book_id %>
<%= f.text_field :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
And in the Book controller, I have
def show
#new_quote = current_user.quotes.create(book_id: params[:id])
end
The quote saves fine but the problem is, since I have this Quote creation statement in the show method, everytime I go to the show.html.erb page of my Book model, it creates a Quote with an empty body.
What can I do to solve this? I was thinking it probably would involve moving this Quote creation to the actual create method of the Quote controller but I don't know how to exactly pass the parameters through.
You could just build that quote, but not save it to the database. Then the user need to send the form to save that record. Just change your show method to:
def show
#new_quote = current_user.quotes.build(book_id: params[:id])
end

Passing Input Text From text_field_tag as a variable for a URL...?

Okay, so I didn't know really how to word this correctly, but here is essentially what I am trying to do.
I am trying to take the text that a user inputs into my search box and pass it on to the URL.
Here is my view page so far:
<h1>What's the weather like by you?</h1>
<br />
<%= form_tag('http://api.wunderground.com/api/myAPIkey/conditions/q/**USER_TEXT_FROM_TEXT_FIELD_TAG**.json',:method =>
'get') do %>
<p>
<%= text_field_tag 'zipcode', params[:search] %>
<%= submit_tag "Check It Out!", :name => nil %>
</p>
<% end %>
I know this is probably such an easy thing to do, but I can't seem to find any way to correctly do it. Thanks for your help!
It looks like you are trying to redirect form submission to different url based on user input.
My no JavaScript sugestion would be to go through your own controller and redirect_to custom url. Something like this:
change your view to:
<h1>What's the weather like by you?</h1>
<br />
<%= form_tag('/weather') do %>
<p>
<%= text_field_tag 'zipcode' %>
<%= submit_tag "Check It Out!", :name => nil %>
</p>
<% end %>
create weather controller:
rails g controller weather create
add this line to your config/route.rb file:
match 'weather' => 'weather#create', via: :post
and modify you app/controllers/weather_controller.rb to look like this:
class WeatherController < ApplicationController
def create
redirect_to "http://api.wunderground.com/api/myAPIkey/conditions/q/#{params[:zipcode].split.join('+')}.json"
end
end
This isn't a nice solution and it isn't the smartest solution, it simply duplicates your code using rails stack. Your question doesn't give many information about what you would like to to with the date returned by api?? Do you really want to simply redirect to given url and see data as json?
I just try to give you another idea how to tackle this problem, its not a final solution.

Rails 3 -- Pass user.id in hidden form field vs using association

Ok so currently I have a form
<div class="field">
<%= f.label :title %><br/>
<%= f.text_field :title %><br/>
<%= f.label :itunesurl %><br />
<%= f.text_field :itunesurl %><br />
<%= f.hidden_field :user_id, :value => current_user.id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
Which passes the current_user.id into the create method of my "app" model which creates it like this before saving it:
#app = App.new(params[:app])
However I have associations of (pseudocode)
user has_many apps
apps belongs_to user
Question: is it safer (so the form doesn't get modified) to do something like this within the create method?
#user = current_user
#app = #user.apps.create(params[:app])
If so... how exactly would I go about actually implementing the code above (its not syntactically correct.. just pseudo)?
Thanks!
Yes using the second way that you have suggested is the best approach
#user = current_user
#app = #user.apps.create(params[:app])
Also make sure you protect yourself from mass assignment, take a read of this http://stephensclafani.com/2010/01/04/ruby-on-rails-secure-mass-assignment/
It's absolutely safer to do it the second way. If you do it the first way, you're trusting the client to state who they are. Anyone could easily modify the form (with firebug, or they could manually submit a POST request with many tools) and end up submitting a form with the current_user of another person.
Make sure you apply this thinking everywhere throughout your app. Do not trust anything the client submits, ever.
The second code snippet is more "RESTful" than the first. By more RESTful, I mean, if an App is a resource that is logically accessed through a User, then by all means use it.
The way you set that up through routes:
resources :users do
resources :apps
end
This will give you paths like user_app_path and new_user_app_path, to which you pass a user ID and an app ID or a new app.
Hope this helps

Anyone know how to save many objects in one form?

I am trying to save many new objects in a form to one pre-existing parent object.
- form_for :parent_object do |f|
This is the beginning of my form. And then within it, I would do:
- 2.times do
- fields_for :child_object do |f|
Now if I were to save this, it would render as an ParentObject_Controller Update action which would fail because Update doesn't identify new objects.
So if I wanted to render the appropriate Save action, I would have to set up like this :
- form_for [#parent_object, #child_object] do |f|
- 2.times do
- fields_for :child_object do |f|
This form then renders the Save action, but only saves the last child_object.
I would show you my controller, but there's hardly a point because its devastatingly erroneous.
My question is, how would you save many new objects in a form to one pre-existing parent object?
I have looked extensively at Ryan Bate's work, and many many other blogs and SO posts regarding this. Nothing seems to really point at specifically creating new child objects for one pre-existing parent object.
Update:
I am under the impression that I have to toggle the parent_object's controller actions for def update.
elsif params[:parent_object][:child_object]
#child_object = Child_Object.new(params[:child_object])
if #child_object.valid? && #parent_object.referrals << #child_object
redirect_to new_parent_object_child_object_path(#parent_object)
else
render :action => :new
end
In debugger, if I I place a debugger at the root of def update, and I write :
>> params[:parent_object]
#=> nil
Interesting! That means that when child_object is send to parent_object controller, the params are not filled out for it. Haha, no idea what to do about it though..
Unfortunately that code doesn't work, it was just my attempt at getting closer. ;)
OK, let's give it another shot. Code taken from RB's screencast with replaced object names:
<% form_for #parent_object do |f| %>
<%= f.error_messages %>
<!-- some field of parent object here -->
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<% f.fields_for :child_objects do |builder| %>
<!-- some fields for child objects -->
<p>
<%= builder.label :content, "Some content for child object" %><br />
<%= builder.text_area :content, :rows => 3 %>
<%= builder.check_box :_destroy %>
<%= builder.label :_destroy, "Remove child object" %>
</p>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
This is a form for #parent_object that has fields for :child_objects. Of course, you've to replace fields with your own.
To make this work, you'll have to build child objects in the constructor:
def new
#parent_object = ParentObject.new
3.times { #parent_object.child_objects.build }
end
Similarly in the edit method, you'd do:
def edit
#parent_object = ParentObject.find(params[:id])
3.times { #parent_object.child_objects.build }
end
To make it work, you need to define the nested attributes for child object:
class ParentObject < ActiveRecord::Base
has_many :child_objects, :dependent => :destroy
accepts_nested_attributes_for :child_objects
end
Hope this helps - this is exactly what RB proposes in his screencasts. Let me know in the comments if you need some further explanation.
-- EDIT --
The update method in the parent_object_controller.rb is just a standard one:
def update
#parent_object = ParentObject.find(params[:id])
if #parent_object.update_attributes(params[:parent_object])
flash[:notice] = "Successfully updated parent object."
redirect_to #parent_object
else
render :action => 'edit'
end
end
But thanks to the accepts_nested_attributes_for in the ParentObject, the nested instances will be created as well.
I didn't include all the model and controller code in this response. You can see the rest of the code by downloading source code for this episode from github.
You can take a look at this answer I gave to a similar question. There're two options: with separate forms, or with a single form.
You'll just have to change the moderate_names_path to the correct path to your parent model instance (and of course the set of fields you want to modify). You can do it with polymorphic_path:
polymorphic_path([#parent_object, #child_object])

Rails "NoMethodError" with sub-resources

I'm a newbie Rails developer who is getting the following error when trying to access the 'new' action on my CityController:
undefined method `cities_path' for #<#<Class:0x104608c18>:0x104606f08>
Extracted source (around line #2):
1: <h1>New City</h1>
2: <%= form_for(#city) do |f| %>
3: <%= f.error_messages %>
4:
5: <div class="field">
As some background, I have a State model with many Cities. I'm getting this error after clicking on the following link coming from a State show page:
<p>Add a city: <%= link_to "Add city", new_state_city_path(#state) %></p>
When I run 'rake:routes' it says this is a legit route...
For more background, here is the CityController 'new' action:
def new
#city = City.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #city }
end
end
Here is the (complete) form in the view:
<%= form_for(#city) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This initially made me think that it's a resources/routes issue since it came back with a mention of 'cities_path' (in fact, that's what another person posting to Stack Overflow had wrong (Rails error "NoMethodError" - My first ruby app). However, that doesn't seem to be the case from what I can see. Here are how my resources look in my routes file:
resources :states do
resources :cities
end
I can get it working when they are not sub-resources, but I really need to keep them as sub-resources for my future plans with the app. Any help would be very much appreciated, since I've been racking my brains on this for more hours than I would care to admit... Thanks!
(Not sure this matters at all, but I'm running the very latest version of Rails 3 beta2).
Your problem is coming from line 2 of your view above, specifically the form_for declaration. As you pointed out, state_city_path is a valid path, but right now, your form is not using this path, it's using city_path. When using nested resources, you need to define everything in terms of that nesting. Your form_for should look something like form_for([#state, #city]) do (I don't remember the exact syntax).
Your follow up answer will work, but isn't exactly the best way to go about it, unless you want to be able to look at cities that are not in the context of a state.
Hope this helps.
PS. The form_for documentation is pretty good, and shows some good examples when using it with resources.
The problem is most likely in this line:
<p>Add a city: <%= link_to "Add city", new_state_city_path(#state) %></p>
It should be :
<p>Add a city: <%= link_to "Add city", new_state_cities_path(#state) %></p>
This is a language nuance, that takes some getting used to. I actually had the same problem. The paths need to be pluralized. I would also check to make sure that your routes.rb file has the pluralized version as well. There should be a line that looks like this:
map.resources :cities
If you have a line that says city instead of cities you should change it to cities. Hope this helps. Another great resource to check out is the #ruby irc channel on freenode, if you run into anymore problems.
Nevermind - I think I figured it out... I needed to have cities defined as a resource on its own, as well as a sub-resource of states. Now it seems to work.

Resources