How do I update a record via params? - ruby-on-rails-3

I want to be able to update a record via params. Something like this:
http://domain.com/api/v1/notes/2190/notify?message=test
But it just returns a page not found. Pretty standard routes going on:
resources :notes, only: [:show] do
post 'notify'
end
My notify method looks like this:
def notify
#note = Note.find(params[:id])
if params[:message]
render text: #note.update_attributes(message: params[:message])
end
end
Do I need to do anything else to permit this functionality? Any advice at all? I can't figure it out. Cheers.

The routes should be something like:
resources :notes, only: :show do
member do
get 'notify'
end
end

Related

how can I make a simple route on rails and can I use it for an ajax form?

Ive been trying to create a simple route on rails, following this instructions
http://guides.rubyonrails.org/routing.html
my problem is that when I want to enter to my method I get a weird error.
I have a controler user and on my routes I wrote something like this
resources :users do
match "/custom/" => "user#custom"
end
So, at my controller I add this code
def custom
#user = User.find(params[:user_id])
end
but when I try to enter doing localhost:3000/users/1/custom I get an error like
uninitialized constant UserController
doing rake routes I can see
user_custom /users/:user_id/custom(.:format) user#custom
Any idea how to solve this problem?
I want this route to submit a form... is it possible to use this route (if i make it run) for use ajax? I want to submit a form.
Thanks
Change your route to:
resources :users do
match "/custom/" => "users#custom"
end
You should avoid the use of match though, since it will be deprecated in Rails 4. Try this instead
resources :users do
get :custom, on: :member
end
get is the verb, :custom the route and on: :member means that you are looking for a /users/:id/custom route instead of a /users/custom one. If you are looking for the latter, do this:
resources :users do
get :custom, on: :collection
end
Another way to do it is like this, which I prefer:
resources :users do
get 'custom', on: :collection
end
That gives you a route of /users/custom. If you were do use on: :member, then it would give you a route of /users/:id/custom.
You can also use a block for defining multiple custom actions for collections or members.
For example:
resources :users do
collection do
get 'custom'
post 'some_other_method'
end
member do
get 'some_action'
end
end

How to use a custom action in Rails' controller, called by a nested route

I want to add a custom action named "campaign" acting in a similar fashion like REST's "new" in the same controller, but it's purpose is different, so I wanted to separate them. Because, this campaign form will have some additional fields. One other alternative would be a passing an extra parameter to "new" action and render different templates for regular "new" action and custom "campaign". But, I wanna figure out why it didn't work out.
So, I come up with the following route ("messages" is the controller having both "new" and "campaign" actions):
get 'users/:user_id/messages/campaign', as: :campaign_user_message
or
resources :users do
resources: messages do
member do
get 'campaign'
end
end
end
At the console output, I'm getting ActiverRecord:RecordNotFound since it does this:
Started GET "/users/1/messages/campaign" for 127.0.0.1 at 2012-12-22 00:14:38 -0800
Processing by MessagesController#show as HTML
Parameters: {"user_id"=>"1", "id"=>"campaign"}
I'm calling the action in this way:
link_to campaign_user_message_path(#user)
if you want to have route such as "/users/1/messages/campaign" you should write smth like that:
resources :users do
resources :messages do
collection do
get 'campaign'
end
end
end
If you write in your way(with member do ... end) you code will generate url "/users/:user_id/messages/:id/campaign". and you should pass #user and #message:
link_to campaign_user_message_path(#user, #message)
I've did something like this overcome to the mentioned issue:
resources :users do
get 'messages/new_campaign' => 'messages#new_campaign'
post 'messages/create_campaign' => 'messages#create_campaign'
end
So, I can use the url helper "user_messages_new_campaign" to GET the action /users/:user_id/messages/new_campaign"

Passing :new to Rails url_for

Maybe I'm stupid but Rails provides this nifty syntax for generating URL's like so:
url_for([user, comment]) # => /users/1/comment/1
Passing :edit allows me to create something like this:
url_for([:edit, user, comment]) # => /users/1/comment/1/edit
but is there some way to do following?
url_for([:new, user, comments]) # => NoMethodError: undefined method `new_user_comments_url'
UPDATE: Added more information.
My routes.rb:
resources :users do
resources :comments
end
resources :posts do
resources :comments
end
My problem here is, that I can't use Rails auto-generated url helper (user_comments_url), because I'm sharing the views for both user comments and post comments.
There are two workarounds (but no one feels like the "Rails"-way) for my problem:
Adding logic to the view, e.g. some if conditions.
Defining my own url helpers like new_parent_comment(user_or_blog).
Ok, found a solution, but I'm not sure if this is the intended one:
url_for([:new, user, :comment]) # => '/users/1/comments/new'
url_for([:new, post, :comment]) # => '/posts/1/comments/new'
Stuck with the same problem, and found next solution (tested on Rails 5.2):
url_for([user, Comment, action: :new])
where Comment model class name.
By the way, action also could be :edit.
According to the Rails Docs url_for uses the class name of the object passed to generate the RESTful route. It also states that with nested routes it can not make this assumption correctly:
If you have a nested route, such as admin_workshop_path you’ll have to call that explicitly (it’s impossible for url_for to guess that route).
I would suggest using a named route here something like new_user_comment_path(). I am assuming you have set up your routes.rb something like:
resources :users do
resources :comments do
end
end
Additionally you can run rake routes to print out the proper names for all your routes.
Hope this helps,
/Salernost
Could this simply be a typo? I think the last line should read comment, not comments:
url_for([:new, user, comment])
(Assuming your comment variable has been defined.)

REST Routes and overriding :id with to_param

My controller is using the default RESTful routes for creating, adding, editing etc
I want to change the default :id to use :guuid. So what I did was:
# routes.rb
resources :posts
# Post Model
class Post < ActiveRecord::Base
def to_param # overridden
guuid
end
end
This works but my modifed REST controller code has something like this
def show
#post = Post.find_by_guuid(params[:id])
#title = "Review"
respond_to do |format|
format.html # show.html.erb
end
end
When I see this this code ..
Post.find_by_guuid(params[:id])
it would seem wrong but it works.
I don't understand why I can't write it out like this:
Post.find_by_guuid(params[:guuid])
Why do I still have to pass in the params[:id] when I'm not using it?
Looking for feedback on whether my approach is correct or anything else to consider.
Even though it works it doesn't always mean it's right.
Type rake routes in your console, and check the output of the routes. You'll see the fragment ':id' in some of them, that's where the params[:id] comes from. It's a rails convention : when you use resources in your routes, the parameter is named id. I don't know if you can change it (while keeping resources; otherwise you could just go with matching rules), but you shouldn't anyway : even if it seems not very logic, it actually has sense, once your understand how rails routing works.

Rails if referrer then do issue

I am trying to figure out the best way to build an if else if statement in the controller around a rails specific referrer. Is there a way to pull the last rails path and use it in the below statement? I think I am close but totally stumped...
This is an update action that will be hit from one form at multiple locations on the site.
I am looking to replace "form_path"
def update
#object = Milestone.find(params[:id])
if #milestone.update_attributes(params[:milestone])
if request.referer == form_path
redirect_to root_path
else
redirect_to object2_path
end
else
....
end
end
Is form_path a variable you're defining somewhere else in the controller? Outside of understanding that, it looks like it should work.
Instead of messing with referer, you could place a hidden_field in the form based on where it's coming from, and pull that out of the params hash.
Something like:
hidden_field_tag :location, controller_name
Then in the controller:
if params[:location] == yadda yadda