Paperclip not saving files with save() - ruby-on-rails-3

I have a little problem with paperclip saving the data passed through the form...
If I'm trying to save the record with .save() it won't save.. When I look in the server/log there are no errors or warnings for the paperclip gem :-/
# trying to save the record with save() -- not working :-/
def create
#baan_import = BaanImport.new(params[:baan_import])
if #baan_import.save
redirect_to(baan_imports_url)
else
render 'new'
end
end
Server-log: (using .save() in controller)
https://gist.github.com/1327347
I just don't get it why it's working if I'm using .create instead of .save()
# trying to save the record with Model.create() -- working!
def create
#baan_import = BaanImport.create(params[:baan_import])
redirect_to(baan_imports_url)
end
Server-log: (using .create() in controller)
https://gist.github.com/1327359
Can some one explain me why it's working with create and not with save??
Thanks,
Michael

Can you show us the BaanImport model. My first guess is you're possibly missing baan_upload in attr_accessible on your model, and as a result, Rails will not let you mass assign the file parameter for upload.
Can you also confirm (would appear as though it's properly set up) that your form has html => {:multipart => true} as an option?

Related

How can I call a controller/view action from a mailer?

In my rails application I've created a business daily report. There is some non-trivial logic for showing it (all kind of customizable parameters that are used for filtering in the model, a controller that calls that model and some non-trivial view for it, for example, some of the columns are row-spanning over several rows).
Now I wish to send this report nightly (with fixed parameters), in addition to the user ability to generate a customize report in my web site. Of course, I wish not to re-write/duplicate my work, including the view.
My question is how can I call the controller action from my mailer so that it will be as if the page was requested by a user (without sending a get request as a browser, which I wish to avoid, of course)?
In answer to your question is if you are generating some sort of pdf report then go with using the wicke_pdf gem does exactly that generates pdfs. To send a report on a nightly basis the best thing for this is to implement some sort of cron job that runs at a particular time which you can do using the whenever gem. You can do something like:
schedule.rb
every :day, :at => '12:00am'
runner User.send_report
end
With this at hand you can see that you call the send_report method sits inside the User model class as shown below:
User.rb
class User < ActiveRecord::Base
def self.send_report
ReportMailer.report_pdf(#user).deliver
end
end
Inside send_report we call the mailer being ReportMailer which is the name of the class for our mailer and the method being report_pdf and pass in the user. BUT remember this is an example I have here I am not sure the exact specified information you want in a report.
Mailer
class ReportMailer< ActionMailer::Base
default :from => DEFAULT_FROM
def report_pdf(user)
#user = user
mail(:subject => "Overtime", :to => user.email) do |format|
format.text # renders report.text.erb for body of email
format.pdf do
attachments["report.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(:pdf => "report",:template => 'report/index.pdf.erb',
:layouts => "pdf.html"))
end
end
end
end
Inside the mailer there are a variety of things going on but the most important part is inside the format.pdf block that uses a variety of wicked_pdf methods (this is assuming that you are using wicked_pdf btw. Inside the block you create a new WickedPDF pdf object and render it to a string. Then provide it with the name of the report, the template and the layout. It is important that you create a template. This usually will where the report will be displaying from. The file type is a .pdf.erb this means that when this view or report is generated in the view the embedded ruby tags are being parsed in and the output is going to be a pdf format.
UserController
def report
#user = User.scoped
if params[:format] == 'pdf'
#Do some stuff here
User.send_report(#users)
end
respond_to do |format|
format.html
format.pdf do
render :pdf => "#{Date.today.strftime('%B')} Report",
:header => {:html => {:template => 'layouts/pdf.html.erb'}}
end
end
end
The key thing you asked that I picked up on.
how can I call the controller action from my mailer
In the controller simply collate a scope of Users, then check the format is a pdf, providing it is do some stuff. Then it will run the method send_report which I earlier highlighted in the user model class (Btw in your words this is the controller calling the model). Then inside the respond block for this there is a format.pdf so that you can generate the pdf. Once again note that you need a template for the core design of the pdf, which is similar to how rails generates an application.html.erb in the layouts. However here we have a pdf.html.erb defined. So that this can be called anywhere again in your application should you want to generate another pdf in your application somewhere else.
Think I've provided a substantial amount of information to set you off in the right direction.

Cannot find FakeInput

I am trying add a fake input to simple_form using the following suggestion (rails simple_form fields not related to the model), but it does not work for me.
This is my HAML code for adding a fake input field.
= f.input :agrees_to_terms, :as => :fake
I put the following class in app/inputs/fake_input.rb
class FakeInput < SimpleForm::Inputs::StringInput
# This method only create a basic input without reading any value from object
def input
template.text_field_tag(attribute_name, nil, input_html_options)
end
end
I get the following runtime error
No input found for fake
I have two initializers that were generated by Rails Composer: simple_form.rb and simple_form_bootstrap.rb
How can I make Rails find my FakeInput class?
I had the same issue, and a server restart resolved it.

working on rails 3 tutorial by hartl and stuck on 12.3.4 - New Status Feed

I'm stuck on the last exercise in the Hartlt book 12.3.4 where you define the status feed for yourself and the users you are following. I'm a Rails newbie so just let me know if I need to post additional information.
When I tail the development log I can see will_paginate fire the SQL to gather the initial records, and the initial page looks fine when it is served up. When I click a link to go to any another page, it appears will_paginate doesn't fire the SQL to get retrieve more data from the database as the next page is server up fine, but there is no data.
There are also no new entries in the development log and maybe I'm wrong, but I think this indicates will_paginate didn't hit the database.
I tried to include all the relevant code snippits below. Happy to send anything that's missing.
Here is my pages_controller.rb
def home
#title = "Home"
if signed_in?
#micropost = Micropost.new
#feed_items = current_user.feed.paginate(:page => params[:page])
end
end
Here is my user.rb
def feed
Micropost.from_users_followed_by(self)
end
Here is my microposts.rb
scope :from_users_followed_by, lambda { |user| followed_by(user) }
private
def self.followed_by(user)
following_ids = %(SELECT followed_id FROM relationships
WHERE follower_id = :user_id)
where("user_id IN (#{following_ids}) OR user_id = :user_id",
:user_id => user)
end
NOTE: In the video tutorial (chapter 12, time = 02:06:00) and the book (page 517, listing 12.44) Harlt uses the variable "followed_ids" instead of "following_ids". In the virgin sample code you can download from his site the variable name is "following_ids", and I have tried it both ways - but it fails.
Bottom line - the dev log shows will_paginate retrieving the first batch of data, but it never goes back to the database for additional data.
Can anyone suggest what I can take a look at to resolve my problem?
Many thanks.
do you have more records than will fit on one page?
If not, it may be that will_paginate is doing a count first.
Then deciding not to load any records.
Get into the console and try it out.
$ rails console
user = User.find(23)
# the same user you're logged in as
user.feed.count
# is it more than one page?
user.feed.paginate(:page => 1)
# 20 records?
user.feed.paginate(:page => 2)
# nothing?
Also:
in your example scope :from_users_followed_by, lambda { |user| followed_by(user) } is redundant.
You may as well just say;
def feed
Micropost.followed_by(self)
end

Rails 3: Manipulating devise "resource" in controller?

I'm using devise & devise_invitable in a rails 3 project, and I'm trying to manipulate some of the 'User' object fields in the devise controller.
The action is question is this:
def update
self.resource = resource_class.accept_invitation!(params[resource_name])
resource.first_name = 'Lemmechangethis'
if resource.errors.empty?
set_flash_message :notice, :updated
sign_in(resource_name, resource)
respond_with resource, :location => after_accept_path_for(resource)
else
respond_with_navigational(resource){ render_with_scope :edit }
end
end
I'd have thought that the (commented out) resource.first_name call would influence resource in much the same way as a model - but it doesn't seem to. I'm still getting a 'blank' validation error on this form.
So, the question is, how do I specify values to the User model in devise (and/or devise_invitable) that will actually be subject to verification?
Any suggestions appreciated,
John
resource does return a User models instance. So the resource.first_name = 'Lemmechangethis' statement does change your User models instance but it doesnot trigger your User models validations, which is probably why resource.errors always returns an empty array. One way to trigger the User models validation is to call resource.valid? for example. You can then check the resource.errors array for specific error messages.

Rails 3 saving a record issue

I have been working with Rails 3.0.5 and Ruby 1.9.2 and I have noticed that a new record doesn't get saved or isn't available for use instantly.
For example
def create
#some_record = Pool.new(params[:pool])
#some_record.users.push(current_user)
if params[:commit] == "Add More"
#some_record.save
#some_record.do_something
elsif params[:commit] == "Save"
do_something_else(params)
elsif params[:commit] == 'Cancel'
redirect_to user_url(current_user)
end
redirect_to some_other_url(current_user)
end
So when I save the record and call some_record.do_something the saved object isn't available instantly. current_user.some_records doesn't contain the newly added record but current_user.some_records.all displays the newly saved record. However on the console I am able to view the newly created record with current_user.some_records.
I'm sure I am missing something fundamental to Rails 3. I have also tried the same with current_user.some_records.build(params[:some_record] and I have the same problem. Does Rails 3 save the object instantly or is there some kind of delayed write/save because the same problem does not occur with Rails 3.0.3.
Also I am not using an authentication plugin like authlogic/devise and I simply save the current_user object to the session. I am not sure what I am doing wrong. WOuld appreciate any help?
Its also a many-to-many association between some_record and users
current_user.some_records
does not contain the newly added record because you did not save the operation after assigning #some_record.users.push(current_user).
All you have to do is to add .save after the assignment and it should work.
The model structure is not clear from your question but let's assumed that current_user belongs_to some_records
To force a database read try this:
current_user.some_records(true)
By default forcereload = false, to override this you should pass true